Bug Summary

File:home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx
Warning:line 1965, column 5
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name window2.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx

/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx

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/toolkit/dialog.hxx>
26#include <vcl/event.hxx>
27#include <vcl/toolkit/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
45using namespace com::sun::star;
46
47namespace vcl {
48
49void 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
91void 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
124void 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
147void 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
158void 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
220IMPL_LINK( Window, ImplTrackTimerHdl, Timer*, pTimer, void )void Window::LinkStubImplTrackTimerHdl(void * instance, Timer
* data) { return static_cast<Window *>(instance)->ImplTrackTimerHdl
(data); } void Window::ImplTrackTimerHdl(Timer* pTimer)
221{
222 ImplSVData* pSVData = ImplGetSVData();
223
224 // if Button-Repeat we have to change the timeout
225 if ( pSVData->mpWinData->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
244void Window::StartTracking( StartTrackingFlags nFlags )
245{
246 ImplSVData* pSVData = ImplGetSVData();
247
248 if ( pSVData->mpWinData->mpTrackWin.get() != this )
249 {
250 if ( pSVData->mpWinData->mpTrackWin )
251 pSVData->mpWinData->mpTrackWin->EndTracking( TrackingEventFlags::Cancel );
252 }
253
254 if ( nFlags & (StartTrackingFlags::ScrollRepeat | StartTrackingFlags::ButtonRepeat) )
255 {
256 pSVData->mpWinData->mpTrackTimer = new AutoTimer;
257
258 if ( nFlags & StartTrackingFlags::ScrollRepeat )
259 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetScrollRepeat() );
260 else
261 pSVData->mpWinData->mpTrackTimer->SetTimeout( MouseSettings::GetButtonStartRepeat() );
262 pSVData->mpWinData->mpTrackTimer->SetInvokeHandler( LINK( this, Window, ImplTrackTimerHdl )::tools::detail::makeLink( ::tools::detail::castTo<Window *
>(this), &Window::LinkStubImplTrackTimerHdl)
);
263 pSVData->mpWinData->mpTrackTimer->SetDebugName( "vcl::Window pSVData->mpWinData->mpTrackTimer" );
264 pSVData->mpWinData->mpTrackTimer->Start();
265 }
266
267 pSVData->mpWinData->mpTrackWin = this;
268 pSVData->mpWinData->mnTrackFlags = nFlags;
269 CaptureMouse();
270}
271
272void Window::EndTracking( TrackingEventFlags nFlags )
273{
274 ImplSVData* pSVData = ImplGetSVData();
275
276 if ( pSVData->mpWinData->mpTrackWin.get() != this )
277 return;
278
279 if ( pSVData->mpWinData->mpTrackTimer )
280 {
281 delete pSVData->mpWinData->mpTrackTimer;
282 pSVData->mpWinData->mpTrackTimer = nullptr;
283 }
284
285 pSVData->mpWinData->mpTrackWin = nullptr;
286 pSVData->mpWinData->mnTrackFlags = StartTrackingFlags::NONE;
287 ReleaseMouse();
288
289 // call EndTracking if required
290 {
291 Point aMousePos( mpWindowImpl->mpFrameData->mnLastMouseX, mpWindowImpl->mpFrameData->mnLastMouseY );
292 if( ImplIsAntiparallel() )
293 {
294 // re-mirror frame pos at pChild
295 const OutputDevice *pOutDev = GetOutDev();
296 pOutDev->ReMirror( aMousePos );
297 }
298
299 MouseEvent aMEvt( ImplFrameToOutput( aMousePos ),
300 mpWindowImpl->mpFrameData->mnClickCount, MouseEventModifiers::NONE,
301 mpWindowImpl->mpFrameData->mnMouseCode,
302 mpWindowImpl->mpFrameData->mnMouseCode );
303 TrackingEvent aTEvt( aMEvt, nFlags | TrackingEventFlags::End );
304 // CompatTracking effectively
305 if (!mpWindowImpl || mpWindowImpl->mbInDispose)
306 return Window::Tracking( aTEvt );
307 else
308 return Tracking( aTEvt );
309 }
310}
311
312bool Window::IsTracking() const
313{
314 return (ImplGetSVData()->mpWinData->mpTrackWin == this);
315}
316
317void Window::StartAutoScroll( StartAutoScrollFlags nFlags )
318{
319 ImplSVData* pSVData = ImplGetSVData();
320
321 if ( pSVData->mpWinData->mpAutoScrollWin.get() != this )
322 {
323 if ( pSVData->mpWinData->mpAutoScrollWin )
324 pSVData->mpWinData->mpAutoScrollWin->EndAutoScroll();
325 }
326
327 pSVData->mpWinData->mpAutoScrollWin = this;
328 pSVData->mpWinData->mnAutoScrollFlags = nFlags;
329 pSVData->maAppData.mpWheelWindow = VclPtr<ImplWheelWindow>::Create( this );
330}
331
332void Window::EndAutoScroll()
333{
334 ImplSVData* pSVData = ImplGetSVData();
335
336 if ( pSVData->mpWinData->mpAutoScrollWin.get() == this )
337 {
338 pSVData->mpWinData->mpAutoScrollWin = nullptr;
339 pSVData->mpWinData->mnAutoScrollFlags = StartAutoScrollFlags::NONE;
340 pSVData->maAppData.mpWheelWindow->ImplStop();
341 pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
342 pSVData->maAppData.mpWheelWindow.disposeAndClear();
343 }
344}
345
346VclPtr<vcl::Window> Window::SaveFocus()
347{
348 ImplSVData* pSVData = ImplGetSVData();
349 if ( pSVData->mpWinData->mpFocusWin )
350 {
351 return pSVData->mpWinData->mpFocusWin;
352 }
353 else
354 return nullptr;
355}
356
357void Window::EndSaveFocus(const VclPtr<vcl::Window>& xFocusWin)
358{
359 if (xFocusWin && !xFocusWin->IsDisposed())
360 {
361 xFocusWin->GrabFocus();
362 }
363}
364
365void Window::SetZoom( const Fraction& rZoom )
366{
367 if ( mpWindowImpl && mpWindowImpl->maZoom != rZoom )
368 {
369 mpWindowImpl->maZoom = rZoom;
370 CompatStateChanged( StateChangedType::Zoom );
371 }
372}
373
374static long WinFloatRound( double fVal )
375{
376 return( fVal > 0.0 ? static_cast<long>( fVal + 0.5 ) : -static_cast<long>( -fVal + 0.5 ) );
377}
378
379void 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
397long 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
409void Window::SetControlFont()
410{
411 if (mpWindowImpl && mpWindowImpl->mpControlFont)
412 {
413 mpWindowImpl->mpControlFont.reset();
414 CompatStateChanged(StateChangedType::ControlFont);
415 }
416}
417
418void 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
438vcl::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
449void 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
457void Window::SetControlForeground()
458{
459 if (mpWindowImpl->mbControlForeground)
460 {
461 mpWindowImpl->maControlForeground = COL_TRANSPARENT;
462 mpWindowImpl->mbControlForeground = false;
463 CompatStateChanged(StateChangedType::ControlForeground);
464 }
465}
466
467void 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
489void 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
497void Window::SetControlBackground()
498{
499 if (mpWindowImpl->mbControlBackground)
500 {
501 mpWindowImpl->maControlBackground = COL_TRANSPARENT;
502 mpWindowImpl->mbControlBackground = false;
503 CompatStateChanged(StateChangedType::ControlBackground);
504 }
505}
506
507void 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
529void 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
537Size 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
545Size 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
553vcl::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
563long 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
577static void lcl_HandleScrollHelper( ScrollBar* pScrl, double nN, bool isMultiplyByLineSize )
578{
579 if ( !pScrl || !nN || !pScrl->IsEnabled() || !pScrl->IsInputEnabled() || pScrl->IsInModalMode() )
580 return;
581
582 long nNewPos = pScrl->GetThumbPos();
583
584 if ( nN == double(-LONG_MAX9223372036854775807L) )
585 nNewPos += pScrl->GetPageSize();
586 else if ( nN == double(LONG_MAX9223372036854775807L) )
587 nNewPos -= pScrl->GetPageSize();
588 else
589 {
590 // allowing both chunked and continuous scrolling
591 if(isMultiplyByLineSize){
592 nN*=pScrl->GetLineSize();
593 }
594
595 const double fVal = nNewPos - nN;
596
597 if ( !o3tl::convertsToAtLeast(fVal, LONG_MIN(-9223372036854775807L -1L)) )
598 nNewPos = LONG_MIN(-9223372036854775807L -1L);
599 else if ( !o3tl::convertsToAtMost(fVal, LONG_MAX9223372036854775807L) )
600 nNewPos = LONG_MAX9223372036854775807L;
601 else
602 nNewPos = static_cast<long>(fVal);
603 }
604
605 pScrl->DoScroll( nNewPos );
606
607}
608
609bool 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(sal_uLong(0xFFFFFFFF)) )
653 {
654 if ( pData->GetDelta() < 0 )
655 nLines = double(-LONG_MAX9223372036854775807L);
656 else
657 nLines = double(LONG_MAX9223372036854775807L);
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
796void 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
803DockingManager* Window::GetDockingManager()
804{
805 return ImplGetDockingManager();
806}
807
808void 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
818::std::vector<VclPtr<vcl::Window> >& Window::ImplGetOwnerDrawList()
819{
820 return ImplGetTopmostFrameWindow()->mpWindowImpl->mpFrameData->maOwnerDrawList;
821}
822
823void Window::SetHelpId( const OString& rHelpId )
824{
825 mpWindowImpl->maHelpId = rHelpId;
826}
827
828const OString& Window::GetHelpId() const
829{
830 return mpWindowImpl->maHelpId;
831}
832
833// --------- old inline methods ---------------
834
835vcl::Window* Window::ImplGetWindow() const
836{
837 if ( mpWindowImpl->mpClientWindow )
838 return mpWindowImpl->mpClientWindow;
839 else
840 return const_cast<vcl::Window*>(this);
841}
842
843ImplFrameData* Window::ImplGetFrameData()
844{
845 return mpWindowImpl ? mpWindowImpl->mpFrameData : nullptr;
846}
847
848SalFrame* Window::ImplGetFrame() const
849{
850 return mpWindowImpl ? mpWindowImpl->mpFrame : nullptr;
851}
852
853weld::Window* Window::GetFrameWeld() const
854{
855 SalFrame* pFrame = ImplGetFrame();
856 return pFrame ? pFrame->GetFrameWeld() : nullptr;
857}
858
859vcl::Window* Window::GetFrameWindow() const
860{
861 SalFrame* pFrame = ImplGetFrame();
862 return pFrame ? pFrame->GetWindow() : nullptr;
863}
864
865vcl::Window* Window::ImplGetParent() const
866{
867 return mpWindowImpl ? mpWindowImpl->mpParent.get() : nullptr;
868}
869
870vcl::Window* Window::ImplGetClientWindow() const
871{
872 return mpWindowImpl ? mpWindowImpl->mpClientWindow.get() : nullptr;
873}
874
875vcl::Window* Window::ImplGetBorderWindow() const
876{
877 return mpWindowImpl ? mpWindowImpl->mpBorderWindow.get() : nullptr;
878}
879
880vcl::Window* Window::ImplGetFirstOverlapWindow()
881{
882 if (!mpWindowImpl)
883 {
884 return nullptr;
885 }
886
887 if ( mpWindowImpl->mbOverlapWin )
888 return this;
889 else
890 return mpWindowImpl->mpOverlapWindow;
891}
892
893const vcl::Window* Window::ImplGetFirstOverlapWindow() const
894{
895 if ( mpWindowImpl->mbOverlapWin )
896 return this;
897 else
898 return mpWindowImpl->mpOverlapWindow;
899}
900
901vcl::Window* Window::ImplGetFrameWindow() const
902{
903 return mpWindowImpl ? mpWindowImpl->mpFrameWindow.get() : nullptr;
904}
905
906bool Window::IsDockingWindow() const
907{
908 return mpWindowImpl && mpWindowImpl->mbDockWin;
909}
910
911bool Window::ImplIsFloatingWindow() const
912{
913 return mpWindowImpl && mpWindowImpl->mbFloatWin;
914}
915
916bool Window::ImplIsSplitter() const
917{
918 return mpWindowImpl && mpWindowImpl->mbSplitter;
919}
920
921bool Window::ImplIsPushButton() const
922{
923 return mpWindowImpl && mpWindowImpl->mbPushButton;
924}
925
926bool Window::ImplIsOverlapWindow() const
927{
928 return mpWindowImpl && mpWindowImpl->mbOverlapWin;
929}
930
931void Window::ImplSetMouseTransparent( bool bTransparent )
932{
933 if (mpWindowImpl)
934 mpWindowImpl->mbMouseTransparent = bTransparent;
935}
936
937Point Window::ImplOutputToFrame( const Point& rPos )
938{
939 return Point( rPos.X()+mnOutOffX, rPos.Y()+mnOutOffY );
940}
941
942Point Window::ImplFrameToOutput( const Point& rPos )
943{
944 return Point( rPos.X()-mnOutOffX, rPos.Y()-mnOutOffY );
945}
946
947void Window::SetCompoundControl( bool bCompound )
948{
949 if (mpWindowImpl)
950 mpWindowImpl->mbCompoundControl = bCompound;
951}
952
953WinBits Window::GetStyle() const
954{
955 return mpWindowImpl ? mpWindowImpl->mnStyle : 0;
956}
957
958WinBits Window::GetPrevStyle() const
959{
960 return mpWindowImpl ? mpWindowImpl->mnPrevStyle : 0;
961}
962
963WindowExtendedStyle Window::GetExtendedStyle() const
964{
965 return mpWindowImpl ? mpWindowImpl->mnExtendedStyle : WindowExtendedStyle::NONE;
966}
967
968void Window::SetType( WindowType nType )
969{
970 if (mpWindowImpl)
971 mpWindowImpl->mnType = nType;
972}
973
974WindowType Window::GetType() const
975{
976 if (mpWindowImpl)
977 return mpWindowImpl->mnType;
978 else
979 return WindowType::NONE;
980}
981
982Dialog* Window::GetParentDialog() const
983{
984 const vcl::Window *pWindow = this;
985
986 while( pWindow )
987 {
988 if( pWindow->IsDialog() )
989 break;
990
991 pWindow = pWindow->GetParent();
992 }
993
994 return const_cast<Dialog *>(dynamic_cast<const Dialog*>(pWindow));
995}
996
997bool Window::IsSystemWindow() const
998{
999 return mpWindowImpl && mpWindowImpl->mbSysWin;
1000}
1001
1002bool Window::IsDialog() const
1003{
1004 return mpWindowImpl && mpWindowImpl->mbDialog;
1005}
1006
1007bool Window::IsMenuFloatingWindow() const
1008{
1009 return mpWindowImpl && mpWindowImpl->mbMenuFloatingWindow;
1010}
1011
1012bool Window::IsToolbarFloatingWindow() const
1013{
1014 return mpWindowImpl && mpWindowImpl->mbToolbarFloatingWindow;
1015}
1016
1017void Window::EnableAllResize()
1018{
1019 mpWindowImpl->mbAllResize = true;
1020}
1021
1022void Window::EnableChildTransparentMode( bool bEnable )
1023{
1024 mpWindowImpl->mbChildTransparent = bEnable;
1025}
1026
1027bool Window::IsChildTransparentModeEnabled() const
1028{
1029 return mpWindowImpl && mpWindowImpl->mbChildTransparent;
1030}
1031
1032bool Window::IsMouseTransparent() const
1033{
1034 return mpWindowImpl && mpWindowImpl->mbMouseTransparent;
1035}
1036
1037bool Window::IsPaintTransparent() const
1038{
1039 return mpWindowImpl && mpWindowImpl->mbPaintTransparent;
1040}
1041
1042void Window::SetDialogControlStart( bool bStart )
1043{
1044 mpWindowImpl->mbDlgCtrlStart = bStart;
1045}
1046
1047bool Window::IsDialogControlStart() const
1048{
1049 return mpWindowImpl && mpWindowImpl->mbDlgCtrlStart;
1050}
1051
1052void Window::SetDialogControlFlags( DialogControlFlags nFlags )
1053{
1054 mpWindowImpl->mnDlgCtrlFlags = nFlags;
1055}
1056
1057DialogControlFlags Window::GetDialogControlFlags() const
1058{
1059 return mpWindowImpl->mnDlgCtrlFlags;
1060}
1061
1062const InputContext& Window::GetInputContext() const
1063{
1064 return mpWindowImpl->maInputContext;
1065}
1066
1067bool Window::IsControlFont() const
1068{
1069 return bool(mpWindowImpl->mpControlFont);
1070}
1071
1072const Color& Window::GetControlForeground() const
1073{
1074 return mpWindowImpl->maControlForeground;
1075}
1076
1077bool Window::IsControlForeground() const
1078{
1079 return mpWindowImpl->mbControlForeground;
1080}
1081
1082const Color& Window::GetControlBackground() const
1083{
1084 return mpWindowImpl->maControlBackground;
1085}
1086
1087bool Window::IsControlBackground() const
1088{
1089 return mpWindowImpl->mbControlBackground;
1090}
1091
1092bool Window::IsInPaint() const
1093{
1094 return mpWindowImpl && mpWindowImpl->mbInPaint;
1095}
1096
1097vcl::Window* Window::GetParent() const
1098{
1099 return mpWindowImpl ? mpWindowImpl->mpRealParent.get() : nullptr;
1100}
1101
1102bool Window::IsVisible() const
1103{
1104 return mpWindowImpl && mpWindowImpl->mbVisible;
1105}
1106
1107bool Window::IsReallyVisible() const
1108{
1109 return mpWindowImpl && mpWindowImpl->mbReallyVisible;
1110}
1111
1112bool Window::IsReallyShown() const
1113{
1114 return mpWindowImpl && mpWindowImpl->mbReallyShown;
1115}
1116
1117bool Window::IsInInitShow() const
1118{
1119 return mpWindowImpl->mbInInitShow;
1120}
1121
1122bool Window::IsEnabled() const
1123{
1124 return mpWindowImpl && !mpWindowImpl->mbDisabled;
1125}
1126
1127bool Window::IsInputEnabled() const
1128{
1129 return mpWindowImpl && !mpWindowImpl->mbInputDisabled;
1130}
1131
1132bool Window::IsAlwaysEnableInput() const
1133{
1134 return mpWindowImpl->meAlwaysInputMode == AlwaysInputEnabled;
1135}
1136
1137ActivateModeFlags Window::GetActivateMode() const
1138{
1139 return mpWindowImpl->mnActivateMode;
1140
1141}
1142
1143bool Window::IsAlwaysOnTopEnabled() const
1144{
1145 return mpWindowImpl->mbAlwaysOnTop;
1146}
1147
1148bool Window::IsDefaultPos() const
1149{
1150 return mpWindowImpl->mbDefPos;
1151}
1152
1153bool Window::IsDefaultSize() const
1154{
1155 return mpWindowImpl->mbDefSize;
1156}
1157
1158Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
1159{
1160 return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
1161}
1162
1163void Window::EnablePaint( bool bEnable )
1164{
1165 mpWindowImpl->mbPaintDisabled = !bEnable;
1166}
1167
1168bool Window::IsPaintEnabled() const
1169{
1170 return !mpWindowImpl->mbPaintDisabled;
1171}
1172
1173bool Window::IsUpdateMode() const
1174{
1175 return !mpWindowImpl->mbNoUpdate;
1176}
1177
1178void Window::SetParentUpdateMode( bool bUpdate )
1179{
1180 mpWindowImpl->mbNoParentUpdate = !bUpdate;
1181}
1182
1183bool Window::IsActive() const
1184{
1185 return mpWindowImpl->mbActive;
1186}
1187
1188GetFocusFlags Window::GetGetFocusFlags() const
1189{
1190 return mpWindowImpl->mnGetFocusFlags;
1191}
1192
1193bool Window::IsCompoundControl() const
1194{
1195 return mpWindowImpl->mbCompoundControl;
1196}
1197
1198bool Window::IsWait() const
1199{
1200 return (mpWindowImpl->mnWaitCount != 0);
1201}
1202
1203vcl::Cursor* Window::GetCursor() const
1204{
1205 if (!mpWindowImpl)
1206 return nullptr;
1207 return mpWindowImpl->mpCursor;
1208}
1209
1210const Fraction& Window::GetZoom() const
1211{
1212 return mpWindowImpl->maZoom;
1213}
1214
1215bool Window::IsZoom() const
1216{
1217 return mpWindowImpl->maZoom.GetNumerator() != mpWindowImpl->maZoom.GetDenominator();
1218}
1219
1220void Window::SetHelpText( const OUString& rHelpText )
1221{
1222 mpWindowImpl->maHelpText = rHelpText;
1223 mpWindowImpl->mbHelpTextDynamic = true;
1224}
1225
1226void Window::SetQuickHelpText( const OUString& rHelpText )
1227{
1228 if (mpWindowImpl)
1229 mpWindowImpl->maQuickHelpText = rHelpText;
1230}
1231
1232const OUString& Window::GetQuickHelpText() const
1233{
1234 return mpWindowImpl->maQuickHelpText;
1235}
1236
1237bool Window::IsCreatedWithToolkit() const
1238{
1239 return mpWindowImpl->mbCreatedWithToolkit;
1240}
1241
1242void Window::SetCreatedWithToolkit( bool b )
1243{
1244 mpWindowImpl->mbCreatedWithToolkit = b;
1245}
1246
1247PointerStyle Window::GetPointer() const
1248{
1249 return mpWindowImpl->maPointer;
1250}
1251
1252VCLXWindow* Window::GetWindowPeer() const
1253{
1254 return mpWindowImpl ? mpWindowImpl->mpVCLXWindow : nullptr;
1255}
1256
1257void Window::SetPosPixel( const Point& rNewPos )
1258{
1259 setPosSizePixel( rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos );
1260}
1261
1262void Window::SetSizePixel( const Size& rNewSize )
1263{
1264 setPosSizePixel( 0, 0, rNewSize.Width(), rNewSize.Height(),
1265 PosSizeFlags::Size );
1266}
1267
1268void Window::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
1269{
1270 setPosSizePixel( rNewPos.X(), rNewPos.Y(),
1271 rNewSize.Width(), rNewSize.Height());
1272}
1273
1274void Window::SetOutputSizePixel( const Size& rNewSize )
1275{
1276 SetSizePixel( Size( rNewSize.Width()+mpWindowImpl->mnLeftBorder+mpWindowImpl->mnRightBorder,
1277 rNewSize.Height()+mpWindowImpl->mnTopBorder+mpWindowImpl->mnBottomBorder ) );
1278}
1279
1280//When a widget wants to renegotiate layout, get toplevel parent dialog and call
1281//resize on it. Mark all intermediate containers (or container-alike) widgets
1282//as dirty for the size remains unchanged, but layout changed circumstances
1283namespace
1284{
1285 bool queue_ungrouped_resize(vcl::Window const *pOrigWindow)
1286 {
1287 bool bSomeoneCares = false;
1288
1289 vcl::Window *pWindow = pOrigWindow->GetParent();
1290 if (pWindow)
1291 {
1292 if (isContainerWindow(*pWindow))
1293 {
1294 bSomeoneCares = true;
1295 }
1296 else if (pWindow->GetType() == WindowType::TABCONTROL)
1297 {
1298 bSomeoneCares = true;
1299 }
1300 pWindow->queue_resize();
1301 }
1302
1303 return bSomeoneCares;
1304 }
1305}
1306
1307void Window::InvalidateSizeCache()
1308{
1309 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1310 pWindowImpl->mnOptimalWidthCache = -1;
1311 pWindowImpl->mnOptimalHeightCache = -1;
1312}
1313
1314void Window::queue_resize(StateChangedType eReason)
1315{
1316 if (IsDisposed())
1317 return;
1318
1319 bool bSomeoneCares = queue_ungrouped_resize(this);
1320
1321 if (eReason != StateChangedType::Visible)
1322 {
1323 InvalidateSizeCache();
1324 }
1325
1326 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1327 if (pWindowImpl->m_xSizeGroup && pWindowImpl->m_xSizeGroup->get_mode() != VclSizeGroupMode::NONE)
1328 {
1329 std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1330 for (VclPtr<vcl::Window> const & pOther : rWindows)
1331 {
1332 if (pOther == this)
1333 continue;
1334 queue_ungrouped_resize(pOther);
1335 }
1336 }
1337
1338 if (bSomeoneCares && !mpWindowImpl->mbInDispose)
1339 {
1340 //fdo#57090 force a resync of the borders of the borderwindow onto this
1341 //window in case they have changed
1342 vcl::Window* pBorderWindow = ImplGetBorderWindow();
1343 if (pBorderWindow)
1344 pBorderWindow->Resize();
1345 }
1346 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
1347 {
1348 Size aSize = GetSizePixel();
1349 if (!aSize.IsEmpty() && GetParentDialog() && !pParent->IsInInitShow())
1350 LogicInvalidate(nullptr);
1351 }
1352}
1353
1354namespace
1355{
1356 VclAlign toAlign(const OUString &rValue)
1357 {
1358 VclAlign eRet = VclAlign::Fill;
1359
1360 if (rValue == "fill")
1361 eRet = VclAlign::Fill;
1362 else if (rValue == "start")
1363 eRet = VclAlign::Start;
1364 else if (rValue == "end")
1365 eRet = VclAlign::End;
1366 else if (rValue == "center")
1367 eRet = VclAlign::Center;
1368 return eRet;
1369 }
1370}
1371
1372bool Window::set_font_attribute(const OString &rKey, const OUString &rValue)
1373{
1374 if (rKey == "weight")
1375 {
1376 vcl::Font aFont(GetControlFont());
1377 if (rValue == "thin")
1378 aFont.SetWeight(WEIGHT_THIN);
1379 else if (rValue == "ultralight")
1380 aFont.SetWeight(WEIGHT_ULTRALIGHT);
1381 else if (rValue == "light")
1382 aFont.SetWeight(WEIGHT_LIGHT);
1383 else if (rValue == "book")
1384 aFont.SetWeight(WEIGHT_SEMILIGHT);
1385 else if (rValue == "normal")
1386 aFont.SetWeight(WEIGHT_NORMAL);
1387 else if (rValue == "medium")
1388 aFont.SetWeight(WEIGHT_MEDIUM);
1389 else if (rValue == "semibold")
1390 aFont.SetWeight(WEIGHT_SEMIBOLD);
1391 else if (rValue == "bold")
1392 aFont.SetWeight(WEIGHT_BOLD);
1393 else if (rValue == "ultrabold")
1394 aFont.SetWeight(WEIGHT_ULTRABOLD);
1395 else
1396 aFont.SetWeight(WEIGHT_BLACK);
1397 SetControlFont(aFont);
1398 }
1399 else if (rKey == "style")
1400 {
1401 vcl::Font aFont(GetControlFont());
1402 if (rValue == "normal")
1403 aFont.SetItalic(ITALIC_NONE);
1404 else if (rValue == "oblique")
1405 aFont.SetItalic(ITALIC_OBLIQUE);
1406 else if (rValue == "italic")
1407 aFont.SetItalic(ITALIC_NORMAL);
1408 SetControlFont(aFont);
1409 }
1410 else if (rKey == "underline")
1411 {
1412 vcl::Font aFont(GetControlFont());
1413 aFont.SetUnderline(toBool(rValue) ? LINESTYLE_SINGLE : LINESTYLE_NONE);
1414 SetControlFont(aFont);
1415 }
1416 else if (rKey == "size")
1417 {
1418 vcl::Font aFont(GetControlFont());
1419 sal_Int32 nHeight = rValue.toInt32() / 1000;
1420 aFont.SetFontHeight(nHeight);
1421 SetControlFont(aFont);
1422 }
1423 else
1424 {
1425 SAL_INFO("vcl.layout", "unhandled font attribute: " << rKey)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unhandled font attribute: "
<< rKey) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled font attribute: " <<
rKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled font attribute: " << rKey; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), (
"/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unhandled font attribute: " << rKey) == 1)
{ ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled font attribute: " <<
rKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled font attribute: " << rKey; ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), (
"/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1425" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1426 return false;
1427 }
1428 return true;
1429}
1430
1431bool Window::set_property(const OString &rKey, const OUString &rValue)
1432{
1433 if ((rKey == "label") || (rKey == "title") || (rKey == "text") )
1434 {
1435 SetText(BuilderUtils::convertMnemonicMarkup(rValue));
1436 }
1437 else if (rKey == "visible")
1438 Show(toBool(rValue));
1439 else if (rKey == "sensitive")
1440 Enable(toBool(rValue));
1441 else if (rKey == "resizable")
1442 {
1443 WinBits nBits = GetStyle();
1444 nBits &= ~WB_SIZEABLE;
1445 if (toBool(rValue))
1446 nBits |= WB_SIZEABLE;
1447 SetStyle(nBits);
1448 }
1449 else if (rKey == "xalign")
1450 {
1451 WinBits nBits = GetStyle();
1452 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1453
1454 float f = rValue.toFloat();
1455 if (f == 0.0)
1456 nBits |= WB_LEFT;
1457 else if (f == 1.0)
1458 nBits |= WB_RIGHT;
1459 else if (f == 0.5)
1460 nBits |= WB_CENTER;
1461
1462 SetStyle(nBits);
1463 }
1464 else if (rKey == "justification")
1465 {
1466 WinBits nBits = GetStyle();
1467 nBits &= ~(WB_LEFT | WB_CENTER | WB_RIGHT);
1468
1469 if (rValue == "left")
1470 nBits |= WB_LEFT;
1471 else if (rValue == "right")
1472 nBits |= WB_RIGHT;
1473 else if (rValue == "center")
1474 nBits |= WB_CENTER;
1475
1476 SetStyle(nBits);
1477 }
1478 else if (rKey == "yalign")
1479 {
1480 WinBits nBits = GetStyle();
1481 nBits &= ~(WB_TOP | WB_VCENTER | WB_BOTTOM);
1482
1483 float f = rValue.toFloat();
1484 if (f == 0.0)
1485 nBits |= WB_TOP;
1486 else if (f == 1.0)
1487 nBits |= WB_BOTTOM;
1488 else if (f == 0.5)
1489 nBits |= WB_CENTER;
1490
1491 SetStyle(nBits);
1492 }
1493 else if (rKey == "wrap")
1494 {
1495 WinBits nBits = GetStyle();
1496 nBits &= ~WB_WORDBREAK;
1497 if (toBool(rValue))
1498 nBits |= WB_WORDBREAK;
1499 SetStyle(nBits);
1500 }
1501 else if (rKey == "height-request")
1502 set_height_request(rValue.toInt32());
1503 else if (rKey == "width-request")
1504 set_width_request(rValue.toInt32());
1505 else if (rKey == "hexpand")
1506 set_hexpand(toBool(rValue));
1507 else if (rKey == "vexpand")
1508 set_vexpand(toBool(rValue));
1509 else if (rKey == "halign")
1510 set_halign(toAlign(rValue));
1511 else if (rKey == "valign")
1512 set_valign(toAlign(rValue));
1513 else if (rKey == "tooltip-markup")
1514 SetQuickHelpText(rValue);
1515 else if (rKey == "tooltip-text")
1516 SetQuickHelpText(rValue);
1517 else if (rKey == "border-width")
1518 set_border_width(rValue.toInt32());
1519 else if (rKey == "margin-start" || rKey == "margin-left")
1520 set_margin_left(rValue.toInt32());
1521 else if (rKey == "margin-end" || rKey == "margin-right")
1522 set_margin_right(rValue.toInt32());
1523 else if (rKey == "margin-top")
1524 set_margin_top(rValue.toInt32());
1525 else if (rKey == "margin-bottom")
1526 set_margin_bottom(rValue.toInt32());
1527 else if (rKey == "hscrollbar-policy")
1528 {
1529 WinBits nBits = GetStyle();
1530 nBits &= ~(WB_AUTOHSCROLL|WB_HSCROLL);
1531 if (rValue == "always")
1532 nBits |= WB_HSCROLL;
1533 else if (rValue == "automatic")
1534 nBits |= WB_AUTOHSCROLL;
1535 SetStyle(nBits);
1536 }
1537 else if (rKey == "vscrollbar-policy")
1538 {
1539 WinBits nBits = GetStyle();
1540 nBits &= ~(WB_AUTOVSCROLL|WB_VSCROLL);
1541 if (rValue == "always")
1542 nBits |= WB_VSCROLL;
1543 else if (rValue == "automatic")
1544 nBits |= WB_AUTOVSCROLL;
1545 SetStyle(nBits);
1546 }
1547 else if (rKey == "accessible-name")
1548 {
1549 SetAccessibleName(rValue);
1550 }
1551 else if (rKey == "accessible-description")
1552 {
1553 SetAccessibleDescription(rValue);
1554 }
1555 else if (rKey == "accessible-role")
1556 {
1557 sal_Int16 role = BuilderUtils::getRoleFromName(rValue.toUtf8());
1558 if (role != com::sun::star::accessibility::AccessibleRole::UNKNOWN)
1559 SetAccessibleRole(role);
1560 }
1561 else if (rKey == "use-markup")
1562 {
1563 //https://live.gnome.org/GnomeGoals/RemoveMarkupInMessages
1564 SAL_WARN_IF(toBool(rValue), "vcl.layout", "Use pango attributes instead of mark-up")do { if (true && (toBool(rValue))) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Use pango attributes instead of mark-up"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Use pango attributes instead of mark-up"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Use pango attributes instead of mark-up"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Use pango attributes instead of mark-up") == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Use pango attributes instead of mark-up"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Use pango attributes instead of mark-up"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1564" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1565 }
1566 else if (rKey == "has-focus")
1567 {
1568 if (toBool(rValue))
1569 GrabFocus();
1570 }
1571 else if (rKey == "can-focus")
1572 {
1573 WinBits nBits = GetStyle();
1574 nBits &= ~(WB_TABSTOP|WB_NOTABSTOP);
1575 if (toBool(rValue))
1576 nBits |= WB_TABSTOP;
1577 else
1578 nBits |= WB_NOTABSTOP;
1579 SetStyle(nBits);
1580 }
1581 else
1582 {
1583 SAL_INFO("vcl.layout", "unhandled property: " << rKey)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO
, "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unhandled property: "
<< rKey) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO
), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled property: " << rKey
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled property: " << rKey; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unhandled property: " << rKey) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "unhandled property: " << rKey
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "unhandled property: " << rKey; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/window2.cxx"
":" "1583" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1584 return false;
1585 }
1586 return true;
1587}
1588
1589void Window::set_height_request(sal_Int32 nHeightRequest)
1590{
1591 if (!mpWindowImpl)
1592 return;
1593
1594 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1595
1596 if ( pWindowImpl->mnHeightRequest != nHeightRequest )
1597 {
1598 pWindowImpl->mnHeightRequest = nHeightRequest;
1599 queue_resize();
1600 }
1601}
1602
1603void Window::set_width_request(sal_Int32 nWidthRequest)
1604{
1605 if (!mpWindowImpl)
1606 return;
1607
1608 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1609
1610 if ( pWindowImpl->mnWidthRequest != nWidthRequest )
1611 {
1612 pWindowImpl->mnWidthRequest = nWidthRequest;
1613 queue_resize();
1614 }
1615}
1616
1617Size Window::get_ungrouped_preferred_size() const
1618{
1619 Size aRet(get_width_request(), get_height_request());
1620 if (aRet.Width() == -1 || aRet.Height() == -1)
1621 {
1622 //cache gets blown away by queue_resize
1623 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1624 if (pWindowImpl->mnOptimalWidthCache == -1 || pWindowImpl->mnOptimalHeightCache == -1)
1625 {
1626 Size aOptimal(GetOptimalSize());
1627 pWindowImpl->mnOptimalWidthCache = aOptimal.Width();
1628 pWindowImpl->mnOptimalHeightCache = aOptimal.Height();
1629 }
1630
1631 if (aRet.Width() == -1)
1632 aRet.setWidth( pWindowImpl->mnOptimalWidthCache );
1633 if (aRet.Height() == -1)
1634 aRet.setHeight( pWindowImpl->mnOptimalHeightCache );
1635 }
1636 return aRet;
1637}
1638
1639Size Window::get_preferred_size() const
1640{
1641 Size aRet(get_ungrouped_preferred_size());
1642
1643 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1644 if (pWindowImpl->m_xSizeGroup)
1645 {
1646 const VclSizeGroupMode eMode = pWindowImpl->m_xSizeGroup->get_mode();
1647 if (eMode != VclSizeGroupMode::NONE)
1648 {
1649 const bool bIgnoreInHidden = pWindowImpl->m_xSizeGroup->get_ignore_hidden();
1650 const std::set<VclPtr<vcl::Window> > &rWindows = pWindowImpl->m_xSizeGroup->get_widgets();
1651 for (auto const& window : rWindows)
1652 {
1653 const vcl::Window *pOther = window;
1654 if (pOther == this)
1655 continue;
1656 if (bIgnoreInHidden && !pOther->IsVisible())
1657 continue;
1658 Size aOtherSize = pOther->get_ungrouped_preferred_size();
1659 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Horizontal)
1660 aRet.setWidth( std::max(aRet.Width(), aOtherSize.Width()) );
1661 if (eMode == VclSizeGroupMode::Both || eMode == VclSizeGroupMode::Vertical)
1662 aRet.setHeight( std::max(aRet.Height(), aOtherSize.Height()) );
1663 }
1664 }
1665 }
1666
1667 return aRet;
1668}
1669
1670VclAlign Window::get_halign() const
1671{
1672 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1673 return pWindowImpl->meHalign;
1674}
1675
1676void Window::set_halign(VclAlign eAlign)
1677{
1678 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1679 pWindowImpl->meHalign = eAlign;
1680}
1681
1682VclAlign Window::get_valign() const
1683{
1684 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1685 return pWindowImpl->meValign;
1686}
1687
1688void Window::set_valign(VclAlign eAlign)
1689{
1690 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1691 pWindowImpl->meValign = eAlign;
1692}
1693
1694bool Window::get_hexpand() const
1695{
1696 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1697 return pWindowImpl->mbHexpand;
1698}
1699
1700void Window::set_hexpand(bool bExpand)
1701{
1702 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1703 pWindowImpl->mbHexpand = bExpand;
1704}
1705
1706bool Window::get_vexpand() const
1707{
1708 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1709 return pWindowImpl->mbVexpand;
1710}
1711
1712void Window::set_vexpand(bool bExpand)
1713{
1714 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1715 pWindowImpl->mbVexpand = bExpand;
1716}
1717
1718bool Window::get_expand() const
1719{
1720 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1721 return pWindowImpl->mbExpand;
1722}
1723
1724void Window::set_expand(bool bExpand)
1725{
1726 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1727 pWindowImpl->mbExpand = bExpand;
1728}
1729
1730VclPackType Window::get_pack_type() const
1731{
1732 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1733 return pWindowImpl->mePackType;
1734}
1735
1736void Window::set_pack_type(VclPackType ePackType)
1737{
1738 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1739 pWindowImpl->mePackType = ePackType;
1740}
1741
1742sal_Int32 Window::get_padding() const
1743{
1744 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1745 return pWindowImpl->mnPadding;
1746}
1747
1748void Window::set_padding(sal_Int32 nPadding)
1749{
1750 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1751 pWindowImpl->mnPadding = nPadding;
1752}
1753
1754bool Window::get_fill() const
1755{
1756 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1757 return pWindowImpl->mbFill;
1758}
1759
1760void Window::set_fill(bool bFill)
1761{
1762 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1763 pWindowImpl->mbFill = bFill;
1764}
1765
1766sal_Int32 Window::get_grid_width() const
1767{
1768 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1769 return pWindowImpl->mnGridWidth;
1770}
1771
1772void Window::set_grid_width(sal_Int32 nCols)
1773{
1774 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1775 pWindowImpl->mnGridWidth = nCols;
1776}
1777
1778sal_Int32 Window::get_grid_left_attach() const
1779{
1780 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1781 return pWindowImpl->mnGridLeftAttach;
1782}
1783
1784void Window::set_grid_left_attach(sal_Int32 nAttach)
1785{
1786 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1787 pWindowImpl->mnGridLeftAttach = nAttach;
1788}
1789
1790sal_Int32 Window::get_grid_height() const
1791{
1792 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1793 return pWindowImpl->mnGridHeight;
1794}
1795
1796void Window::set_grid_height(sal_Int32 nRows)
1797{
1798 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1799 pWindowImpl->mnGridHeight = nRows;
1800}
1801
1802sal_Int32 Window::get_grid_top_attach() const
1803{
1804 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1805 return pWindowImpl->mnGridTopAttach;
1806}
1807
1808void Window::set_grid_top_attach(sal_Int32 nAttach)
1809{
1810 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1811 pWindowImpl->mnGridTopAttach = nAttach;
1812}
1813
1814void Window::set_border_width(sal_Int32 nBorderWidth)
1815{
1816 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1817 pWindowImpl->mnBorderWidth = nBorderWidth;
1818}
1819
1820sal_Int32 Window::get_border_width() const
1821{
1822 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1823 return pWindowImpl->mnBorderWidth;
1824}
1825
1826void Window::set_margin_left(sal_Int32 nWidth)
1827{
1828 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1829 if (pWindowImpl->mnMarginLeft != nWidth)
1830 {
1831 pWindowImpl->mnMarginLeft = nWidth;
1832 queue_resize();
1833 }
1834}
1835
1836sal_Int32 Window::get_margin_left() const
1837{
1838 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1839 return pWindowImpl->mnMarginLeft;
1840}
1841
1842void Window::set_margin_right(sal_Int32 nWidth)
1843{
1844 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1845 if (pWindowImpl->mnMarginRight != nWidth)
1846 {
1847 pWindowImpl->mnMarginRight = nWidth;
1848 queue_resize();
1849 }
1850}
1851
1852sal_Int32 Window::get_margin_right() const
1853{
1854 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1855 return pWindowImpl->mnMarginRight;
1856}
1857
1858void Window::set_margin_top(sal_Int32 nWidth)
1859{
1860 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1861 if (pWindowImpl->mnMarginTop != nWidth)
1862 {
1863 pWindowImpl->mnMarginTop = nWidth;
1864 queue_resize();
1865 }
1866}
1867
1868sal_Int32 Window::get_margin_top() const
1869{
1870 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1871 return pWindowImpl->mnMarginTop;
1872}
1873
1874void Window::set_margin_bottom(sal_Int32 nWidth)
1875{
1876 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1877 if (pWindowImpl->mnMarginBottom != nWidth)
1878 {
1879 pWindowImpl->mnMarginBottom = nWidth;
1880 queue_resize();
1881 }
1882}
1883
1884sal_Int32 Window::get_margin_bottom() const
1885{
1886 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1887 return pWindowImpl->mnMarginBottom;
1888}
1889
1890sal_Int32 Window::get_height_request() const
1891{
1892 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1893 return pWindowImpl->mnHeightRequest;
1894}
1895
1896sal_Int32 Window::get_width_request() const
1897{
1898 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1899 return pWindowImpl->mnWidthRequest;
1900}
1901
1902bool Window::get_secondary() const
1903{
1904 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1905 return pWindowImpl->mbSecondary;
1906}
1907
1908void Window::set_secondary(bool bSecondary)
1909{
1910 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1911 pWindowImpl->mbSecondary = bSecondary;
1912}
1913
1914bool Window::get_non_homogeneous() const
1915{
1916 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1917 return pWindowImpl->mbNonHomogeneous;
1918}
1919
1920void Window::set_non_homogeneous(bool bNonHomogeneous)
1921{
1922 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1923 pWindowImpl->mbNonHomogeneous = bNonHomogeneous;
1924}
1925
1926void Window::add_to_size_group(const std::shared_ptr<VclSizeGroup>& xGroup)
1927{
1928 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1929 //To-Do, multiple groups
1930 pWindowImpl->m_xSizeGroup = xGroup;
1931 pWindowImpl->m_xSizeGroup->insert(this);
1932 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1933 queue_resize();
1934}
1935
1936void Window::remove_from_all_size_groups()
1937{
1938 WindowImpl *pWindowImpl = mpWindowImpl->mpBorderWindow ? mpWindowImpl->mpBorderWindow->mpWindowImpl.get() : mpWindowImpl.get();
1939 //To-Do, multiple groups
1940 if (pWindowImpl->m_xSizeGroup)
1941 {
1942 if (VclSizeGroupMode::NONE != pWindowImpl->m_xSizeGroup->get_mode())
1943 queue_resize();
1944 pWindowImpl->m_xSizeGroup->erase(this);
1945 pWindowImpl->m_xSizeGroup.reset();
1946 }
1947}
1948
1949void Window::add_mnemonic_label(FixedText *pLabel)
1950{
1951 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1952 if (std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel)) != v.end())
1953 return;
1954 v.emplace_back(pLabel);
1955 pLabel->set_mnemonic_widget(this);
1956}
1957
1958void Window::remove_mnemonic_label(FixedText *pLabel)
1959{
1960 std::vector<VclPtr<FixedText> >& v = mpWindowImpl->m_aMnemonicLabels;
1961 auto aFind = std::find(v.begin(), v.end(), VclPtr<FixedText>(pLabel));
1
Calling constructor for 'VclPtr<FixedText>'
6
Returning from constructor for 'VclPtr<FixedText>'
7
Calling implicit destructor for 'VclPtr<FixedText>'
8
Calling '~Reference'
15
Returning from '~Reference'
16
Returning from destructor for 'VclPtr<FixedText>'
1962 if (aFind == v.end())
17
Taking false branch
1963 return;
1964 v.erase(aFind);
1965 pLabel->set_mnemonic_widget(nullptr);
18
Use of memory after it is freed
1966}
1967
1968const std::vector<VclPtr<FixedText> >& Window::list_mnemonic_labels() const
1969{
1970 return mpWindowImpl->m_aMnemonicLabels;
1971}
1972
1973} /* namespace vcl */
1974
1975void DrawFocusRect(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
1976{
1977 const int nBorder = 1;
1978 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1979 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Bottom()-nBorder+1), Size(rRect.GetWidth(), nBorder)), InvertFlags::N50);
1980 rRenderContext.Invert(tools::Rectangle(Point(rRect.Left(), rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1981 rRenderContext.Invert(tools::Rectangle(Point(rRect.Right()-nBorder+1, rRect.Top()+nBorder), Size(nBorder, rRect.GetHeight()-(nBorder*2))), InvertFlags::N50);
1982}
1983
1984/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

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#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
2
Calling constructor for 'Reference<FixedText>'
5
Returning from constructor for 'Reference<FixedText>'
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
3
Assuming field 'm_pBody' is non-null
4
Taking true branch
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
8.1
Field 'm_pBody' is non-null
)
9
Taking true branch
113 m_pBody->release();
10
Calling 'VclReferenceBase::release'
14
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
11
Assuming the condition is true
12
Taking true branch
40 delete this;
13
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif