Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 127, column 13
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 floatwin.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/floatwin.cxx

/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.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 <svdata.hxx>
21#include <brdwin.hxx>
22#include <window.h>
23#include <salframe.hxx>
24#include <helpwin.hxx>
25
26#include <comphelper/lok.hxx>
27#include <sal/log.hxx>
28#include <vcl/layout.hxx>
29#include <vcl/svapp.hxx>
30#include <vcl/wrkwin.hxx>
31#include <vcl/event.hxx>
32#include <vcl/toolbox.hxx>
33#include <vcl/floatwin.hxx>
34#include <vcl/settings.hxx>
35#include <vcl/IDialogRenderable.hxx>
36
37class FloatingWindow::ImplData
38{
39public:
40 ImplData();
41
42 VclPtr<ToolBox> mpBox;
43 tools::Rectangle maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
44 Point maPos; // position of the floating window wrt. parent
45 Point maLOKTwipsPos; ///< absolute position of the floating window in the document - in twips (for toplevel floating windows).
46};
47
48FloatingWindow::ImplData::ImplData()
49{
50 mpBox = nullptr;
51}
52
53tools::Rectangle& FloatingWindow::ImplGetItemEdgeClipRect()
54{
55 return mpImplData->maItemEdgeClipRect;
56}
57
58void FloatingWindow::ImplInitFloating( vcl::Window* pParent, WinBits nStyle )
59{
60 mpImplData.reset(new ImplData);
61
62 mpWindowImpl->mbFloatWin = true;
63 mbInCleanUp = false;
64 mbGrabFocus = false;
65
66 SAL_WARN_IF(!pParent, "vcl", "FloatWindow::FloatingWindow(): - pParent == NULL!")do { if (true && (!pParent)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "66" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "FloatWindow::FloatingWindow(): - pParent == NULL!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "66" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "FloatWindow::FloatingWindow(): - pParent == NULL!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "66" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "FloatWindow::FloatingWindow(): - pParent == NULL!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "66" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
67
68 if (!pParent)
69 pParent = ImplGetSVData()->maFrameData.mpAppWin;
70
71 SAL_WARN_IF(!pParent, "vcl", "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists")do { if (true && (!pParent)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "71" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "71" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"
), ("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "71" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"),
("/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
":" "71" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
72
73 // no Border, then we don't need a border window
74 if (!nStyle)
75 {
76 mpWindowImpl->mbOverlapWin = true;
77 nStyle |= WB_DIALOGCONTROL;
78 ImplInit(pParent, nStyle, nullptr);
79 }
80 else
81 {
82 if (!(nStyle & WB_NODIALOGCONTROL))
83 nStyle |= WB_DIALOGCONTROL;
84
85 if (nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)
86 && !(nStyle & WB_OWNERDRAWDECORATION))
87 {
88 WinBits nFloatWinStyle = nStyle;
89 // #99154# floaters are not closeable by default anymore, eg fullscreen floater
90 // nFloatWinStyle |= WB_CLOSEABLE;
91 mpWindowImpl->mbFrame = true;
92 mpWindowImpl->mbOverlapWin = true;
93 ImplInit(pParent, nFloatWinStyle & ~WB_BORDER, nullptr);
94 }
95 else
96 {
97 VclPtr<ImplBorderWindow> pBorderWin;
98 BorderWindowStyle nBorderStyle = BorderWindowStyle::Float;
99
100 if (nStyle & WB_OWNERDRAWDECORATION)
101 nBorderStyle |= BorderWindowStyle::Frame;
102 else
103 nBorderStyle |= BorderWindowStyle::Overlap;
104
105 if ((nStyle & WB_SYSTEMWINDOW) && !(nStyle & (WB_MOVEABLE | WB_SIZEABLE)))
106 {
107 nBorderStyle |= BorderWindowStyle::Frame;
108 nStyle |= WB_CLOSEABLE; // make undecorated floaters closeable
109 }
110 pBorderWin = VclPtr<ImplBorderWindow>::Create(pParent, nStyle, nBorderStyle);
111 ImplInit(pBorderWin, nStyle & ~WB_BORDER, nullptr);
112 pBorderWin->mpWindowImpl->mpClientWindow = this;
113 pBorderWin->GetBorder(mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder,
114 mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder);
115 pBorderWin->SetDisplayActive(true);
116 mpWindowImpl->mpBorderWindow = pBorderWin;
117 mpWindowImpl->mpRealParent = pParent;
118 }
119 }
120 SetActivateMode( ActivateModeFlags::NONE );
121
122 mpNextFloat = nullptr;
123 mpFirstPopupModeWin = nullptr;
124 mnPostId = nullptr;
125 mnTitle = (nStyle & (WB_MOVEABLE | WB_POPUP)) ? FloatWinTitleType::Normal : FloatWinTitleType::NONE;
126 mnOldTitle = mnTitle;
127 mnPopupModeFlags = FloatWinPopupFlags::NONE;
128 mbInPopupMode = false;
129 mbPopupMode = false;
130 mbPopupModeCanceled = false;
131 mbPopupModeTearOff = false;
132 mbMouseDown = false;
133
134 ImplInitSettings();
135}
136
137void FloatingWindow::ImplInitSettings()
138{
139 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
140
141 Color aColor;
142 if (IsControlBackground())
143 aColor = GetControlBackground();
144 else if (Window::GetStyle() & WB_3DLOOK)
145 aColor = rStyleSettings.GetFaceColor();
146 else
147 aColor = rStyleSettings.GetWindowColor();
148 SetBackground(aColor);
149}
150
151FloatingWindow::FloatingWindow(vcl::Window* pParent, WinBits nStyle) :
152 SystemWindow(WindowType::FLOATINGWINDOW)
153{
154 ImplInitFloating(pParent, nStyle);
155}
156
157FloatingWindow::FloatingWindow(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame> &rFrame)
158 : SystemWindow(WindowType::FLOATINGWINDOW)
159 , mpNextFloat(nullptr)
160 , mpFirstPopupModeWin(nullptr)
161 , mnPostId(nullptr)
162 , mnPopupModeFlags(FloatWinPopupFlags::NONE)
163 , mnTitle(FloatWinTitleType::Unknown)
164 , mnOldTitle(FloatWinTitleType::Unknown)
165 , mbInPopupMode(false)
166 , mbPopupMode(false)
167 , mbPopupModeCanceled(false)
168 , mbPopupModeTearOff(false)
169 , mbMouseDown(false)
170 , mbGrabFocus(false)
171 , mbInCleanUp(false)
172{
173 loadUI(pParent, rID, rUIXMLDescription, rFrame);
174}
175
176//Find the real parent stashed in mpDialogParent.
177void FloatingWindow::doDeferredInit(WinBits nBits)
178{
179 vcl::Window *pParent = mpDialogParent;
180 mpDialogParent = nullptr;
181 ImplInitFloating(pParent, nBits);
182 mbIsDeferredInit = false;
183}
184
185void FloatingWindow::ApplySettings(vcl::RenderContext& rRenderContext)
186{
187 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
188
189 Color aColor;
190 if (Window::GetStyle() & WB_3DLOOK)
191 aColor = rStyleSettings.GetFaceColor();
192 else
193 aColor = rStyleSettings.GetWindowColor();
194
195 ApplyControlBackground(rRenderContext, aColor);
196}
197
198FloatingWindow::~FloatingWindow()
199{
200 disposeOnce();
201 assert (!mnPostId)(static_cast <bool> (!mnPostId) ? void (0) : __assert_fail
("!mnPostId", "/home/maarten/src/libreoffice/core/vcl/source/window/floatwin.cxx"
, 201, __extension__ __PRETTY_FUNCTION__))
;
202}
203
204void FloatingWindow::dispose()
205{
206 ReleaseLOKNotifier();
207
208 if (mpImplData)
1
Taking true branch
209 {
210 if( mbPopupModeCanceled )
2
Assuming field 'mbPopupModeCanceled' is false
3
Taking false branch
211 // indicates that ESC key was pressed
212 // will be handled in Window::ImplGrabFocus()
213 SetDialogControlFlags( GetDialogControlFlags() | DialogControlFlags::FloatWinPopupModeEndCancel );
214
215 if ( IsInPopupMode() )
4
Assuming the condition is true
5
Taking true branch
216 EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll | FloatWinPopupEndFlags::DontCallHdl );
6
Calling 'FloatingWindow::EndPopupMode'
217
218 if ( mnPostId )
219 Application::RemoveUserEvent( mnPostId );
220 mnPostId = nullptr;
221 }
222
223 mpImplData.reset();
224
225 mpNextFloat.clear();
226 mpFirstPopupModeWin.clear();
227 mxPrevFocusWin.clear();
228 SystemWindow::dispose();
229}
230
231Point FloatingWindow::CalcFloatingPosition( vcl::Window* pWindow, const tools::Rectangle& rRect, FloatWinPopupFlags nFlags, sal_uInt16& rArrangeIndex )
232{
233 return ImplCalcPos( pWindow, rRect, nFlags, rArrangeIndex );
234}
235
236Point FloatingWindow::ImplCalcPos(vcl::Window* pWindow,
237 const tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
238 sal_uInt16& rArrangeIndex, Point* pLOKTwipsPos)
239{
240 // get window position
241 Point aPos;
242 Size aSize = ::isLayoutEnabled(pWindow) ? pWindow->get_preferred_size() : pWindow->GetSizePixel();
243 tools::Rectangle aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
244 FloatingWindow *pFloatingWindow = dynamic_cast<FloatingWindow*>( pWindow );
245
246 // convert...
247 vcl::Window* pW = pWindow;
248 if ( pW->mpWindowImpl->mpRealParent )
249 pW = pW->mpWindowImpl->mpRealParent;
250
251 tools::Rectangle normRect( rRect ); // rRect is already relative to top-level window
252 normRect.SetPos( pW->ScreenToOutputPixel( normRect.TopLeft() ) );
253
254 bool bRTL = AllSettings::GetLayoutRTL();
255
256 tools::Rectangle devRect( pW->OutputToAbsoluteScreenPixel( normRect.TopLeft() ),
257 pW->OutputToAbsoluteScreenPixel( normRect.BottomRight() ) );
258
259 tools::Rectangle devRectRTL( devRect );
260 if( bRTL )
261 // create a rect that can be compared to desktop coordinates
262 devRectRTL = pW->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect );
263 if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
264 aScreenRect = Application::GetScreenPosSizePixel(
265 Application::GetBestScreen( bRTL ? devRectRTL : devRect ) );
266
267 FloatWinPopupFlags nArrangeAry[5];
268 sal_uInt16 nArrangeAttempts = 5;
269 Point e1,e2; // the common edge between the item rect and the floating window
270
271 if ( nFlags & FloatWinPopupFlags::Left )
272 {
273 nArrangeAry[0] = FloatWinPopupFlags::Left;
274 nArrangeAry[1] = FloatWinPopupFlags::Right;
275 nArrangeAry[2] = FloatWinPopupFlags::Up;
276 nArrangeAry[3] = FloatWinPopupFlags::Down;
277 nArrangeAry[4] = FloatWinPopupFlags::Left;
278 }
279 else if ( nFlags & FloatWinPopupFlags::Right )
280 {
281 nArrangeAry[0] = FloatWinPopupFlags::Right;
282 nArrangeAry[1] = FloatWinPopupFlags::Left;
283 nArrangeAry[2] = FloatWinPopupFlags::Up;
284 nArrangeAry[3] = FloatWinPopupFlags::Down;
285 nArrangeAry[4] = FloatWinPopupFlags::Right;
286 }
287 else if ( nFlags & FloatWinPopupFlags::Up )
288 {
289 nArrangeAry[0] = FloatWinPopupFlags::Up;
290 nArrangeAry[1] = FloatWinPopupFlags::Down;
291 if (nFlags & FloatWinPopupFlags::NoHorzPlacement)
292 {
293 nArrangeAry[2] = FloatWinPopupFlags::Up;
294 nArrangeAttempts = 3;
295 }
296 else
297 {
298 nArrangeAry[2] = FloatWinPopupFlags::Right;
299 nArrangeAry[3] = FloatWinPopupFlags::Left;
300 nArrangeAry[4] = FloatWinPopupFlags::Up;
301 }
302 }
303 else
304 {
305 nArrangeAry[0] = FloatWinPopupFlags::Down;
306 nArrangeAry[1] = FloatWinPopupFlags::Up;
307 if (nFlags & FloatWinPopupFlags::NoHorzPlacement)
308 {
309 nArrangeAry[2] = FloatWinPopupFlags::Down;
310 nArrangeAttempts = 3;
311 }
312 else
313 {
314 nArrangeAry[2] = FloatWinPopupFlags::Right;
315 nArrangeAry[3] = FloatWinPopupFlags::Left;
316 nArrangeAry[4] = FloatWinPopupFlags::Down;
317 }
318 }
319
320 sal_uInt16 nArrangeIndex = 0;
321 const bool bLOKActive = comphelper::LibreOfficeKit::isActive();
322
323 for ( ; nArrangeIndex < nArrangeAttempts; nArrangeIndex++ )
324 {
325 bool bBreak = true;
326 switch ( nArrangeAry[nArrangeIndex] )
327 {
328
329 case FloatWinPopupFlags::Left:
330 aPos.setX( devRect.Left()-aSize.Width()+1 );
331 aPos.setY( devRect.Top() );
332 aPos.AdjustY( -(pWindow->mpWindowImpl->mnTopBorder) );
333 if( bRTL )
334 {
335 if( (devRectRTL.Right()+aSize.Width()) > aScreenRect.Right() )
336 bBreak = false;
337 }
338 else
339 {
340 if ( aPos.X() < aScreenRect.Left() )
341 bBreak = false;
342 }
343 if (bBreak || bLOKActive)
344 {
345 e1 = devRect.TopLeft();
346 e2 = devRect.BottomLeft();
347 // set non-zero width
348 e2.AdjustX( 1 );
349 // don't clip corners
350 e1.AdjustY( 1 );
351 e2.AdjustY( -1 );
352 }
353 break;
354 case FloatWinPopupFlags::Right:
355 aPos = devRect.TopRight();
356 aPos.AdjustY( -(pWindow->mpWindowImpl->mnTopBorder) );
357 if( bRTL )
358 {
359 if( (devRectRTL.Left() - aSize.Width()) < aScreenRect.Left() )
360 bBreak = false;
361 }
362 else
363 {
364 if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
365 bBreak = false;
366 }
367 if (bBreak || bLOKActive)
368 {
369 e1 = devRect.TopRight();
370 e2 = devRect.BottomRight();
371 // set non-zero width
372 e2.AdjustX( 1 );
373 // don't clip corners
374 e1.AdjustY( 1 );
375 e2.AdjustY( -1 );
376 }
377 break;
378 case FloatWinPopupFlags::Up:
379 aPos.setX( devRect.Left() );
380 aPos.setY( devRect.Top()-aSize.Height()+1 );
381 if ( aPos.Y() < aScreenRect.Top() )
382 bBreak = false;
383 if (bBreak || bLOKActive)
384 {
385 e1 = devRect.TopLeft();
386 e2 = devRect.TopRight();
387 // set non-zero height
388 e2.AdjustY( 1 );
389 // don't clip corners
390 e1.AdjustX( 1 );
391 e2.AdjustX( -1 );
392 }
393 break;
394 case FloatWinPopupFlags::Down:
395 aPos = devRect.BottomLeft();
396 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
397 bBreak = false;
398 if (bBreak || bLOKActive)
399 {
400 e1 = devRect.BottomLeft();
401 e2 = devRect.BottomRight();
402 // set non-zero height
403 e2.AdjustY( 1 );
404 // don't clip corners
405 e1.AdjustX( 1 );
406 e2.AdjustX( -1 );
407 }
408 break;
409 default: break;
410 }
411
412 // no further adjustment for LibreOfficeKit
413 if (bLOKActive)
414 break;
415
416 // adjust if necessary
417 if (bBreak)
418 {
419 if ( (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Left) ||
420 (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Right) )
421 {
422 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
423 {
424 aPos.setY( devRect.Bottom()-aSize.Height()+1 );
425 if ( aPos.Y() < aScreenRect.Top() )
426 aPos.setY( aScreenRect.Top() );
427 }
428 }
429 else
430 {
431 if( bRTL )
432 {
433 if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
434 aPos.AdjustX( -(aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1) );
435 }
436 else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
437 {
438 aPos.setX( devRect.Right()-aSize.Width()+1 );
439 if ( aPos.X() < aScreenRect.Left() )
440 aPos.setX( aScreenRect.Left() );
441 }
442 }
443 }
444
445 if ( bBreak )
446 break;
447 }
448 if (nArrangeIndex >= nArrangeAttempts)
449 nArrangeIndex = nArrangeAttempts - 1;
450
451 rArrangeIndex = nArrangeIndex;
452
453 aPos = pW->AbsoluteScreenToOutputPixel( aPos );
454
455 // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
456 if( pFloatingWindow && pFloatingWindow->mpImplData->mpBox )
457 {
458 pFloatingWindow->mpImplData->maItemEdgeClipRect =
459 tools::Rectangle( e1, e2 );
460 }
461
462 if (bLOKActive && pLOKTwipsPos)
463 {
464 if (pW->IsMapModeEnabled() || pW->GetMapMode().GetMapUnit() == MapUnit::MapPixel)
465 {
466 // if we use pW->LogicToLogic(aPos, pW->GetMapMode(), MapMode(MapUnit::MapTwip)),
467 // for pixel conversions when map mode is not enabled, we get
468 // a 20 twips per pixel conversion since LogicToLogic uses
469 // a fixed 72 dpi value, instead of a correctly computed output
470 // device dpi or at least the most commonly used 96 dpi value;
471 // and anyway the following is what we already do in
472 // ScGridWindow::LogicInvalidate when map mode is not enabled.
473
474 *pLOKTwipsPos = pW->PixelToLogic(aPos, MapMode(MapUnit::MapTwip));
475 }
476 else
477 {
478 *pLOKTwipsPos = OutputDevice::LogicToLogic(aPos, pW->GetMapMode(), MapMode(MapUnit::MapTwip));
479 }
480 }
481
482 // caller expects coordinates relative to top-level win
483 return pW->OutputToScreenPixel( aPos );
484}
485
486Point FloatingWindow::ImplConvertToAbsPos(vcl::Window* pReference, const Point& rPos)
487{
488 Point aAbsolute( rPos );
489
490 const OutputDevice *pWindowOutDev = pReference->GetOutDev();
491
492 // compare coordinates in absolute screen coordinates
493 if( pReference->HasMirroredGraphics() )
494 {
495 if(!pReference->IsRTLEnabled() )
496 pWindowOutDev->ReMirror( aAbsolute );
497
498 tools::Rectangle aRect( pReference->ScreenToOutputPixel(aAbsolute), Size(1,1) ) ;
499 aRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect );
500 aAbsolute = aRect.TopLeft();
501 }
502 else
503 aAbsolute = pReference->OutputToAbsoluteScreenPixel(
504 pReference->ScreenToOutputPixel(rPos) );
505
506 return aAbsolute;
507}
508
509tools::Rectangle FloatingWindow::ImplConvertToAbsPos(vcl::Window* pReference, const tools::Rectangle& rRect)
510{
511 tools::Rectangle aFloatRect = rRect;
512
513 const OutputDevice *pParentWinOutDev = pReference->GetOutDev();
514
515 // compare coordinates in absolute screen coordinates
516 // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
517 if( pReference->HasMirroredGraphics() )
518 {
519 if(!pReference->IsRTLEnabled() )
520 pParentWinOutDev->ReMirror(aFloatRect);
521
522 aFloatRect.SetPos(pReference->ScreenToOutputPixel(aFloatRect.TopLeft()));
523 aFloatRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel(aFloatRect);
524 }
525 else
526 aFloatRect.SetPos(pReference->OutputToAbsoluteScreenPixel(pReference->ScreenToOutputPixel(rRect.TopLeft())));
527 return aFloatRect;
528}
529
530FloatingWindow* FloatingWindow::ImplFloatHitTest( vcl::Window* pReference, const Point& rPos, bool& rbHitTestInsideRect )
531{
532 FloatingWindow* pWin = this;
533 rbHitTestInsideRect = false;
534
535 Point aAbsolute(FloatingWindow::ImplConvertToAbsPos(pReference, rPos));
536
537 do
538 {
539 // compute the floating window's size in absolute screen coordinates
540
541 // use the border window to have the exact position
542 vcl::Window *pBorderWin = pWin->GetWindow( GetWindowType::Border );
543 if (!pBorderWin)
544 break;
545
546 // the top-left corner in output coordinates ie (0,0)
547 tools::Rectangle devRect( pBorderWin->ImplOutputToUnmirroredAbsoluteScreenPixel( tools::Rectangle( Point(), pBorderWin->GetSizePixel()) ) ) ;
548 if ( devRect.IsInside( aAbsolute ) )
549 {
550 // inside the window
551 return pWin;
552 }
553
554 // test, if mouse is in rectangle, (this is typically the rect of the active
555 // toolbox item or similar)
556 // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
557 // is already in absolute device coordinates
558 if ( pWin->maFloatRect.IsInside( aAbsolute ) )
559 {
560 rbHitTestInsideRect = true;
561 return pWin;
562 }
563
564 pWin = pWin->mpNextFloat;
565 }
566 while ( pWin );
567
568 return nullptr;
569}
570
571FloatingWindow* FloatingWindow::ImplFindLastLevelFloat()
572{
573 FloatingWindow* pWin = this;
574 FloatingWindow* pLastFoundWin = pWin;
575
576 do
577 {
578 if ( pWin->GetPopupModeFlags() & FloatWinPopupFlags::NewLevel )
579 pLastFoundWin = pWin;
580
581 pWin = pWin->mpNextFloat;
582 }
583 while ( pWin );
584
585 return pLastFoundWin;
586}
587
588bool FloatingWindow::ImplIsFloatPopupModeWindow( const vcl::Window* pWindow )
589{
590 FloatingWindow* pWin = this;
591
592 do
593 {
594 if ( pWin->mpFirstPopupModeWin == pWindow )
595 return true;
596
597 pWin = pWin->mpNextFloat;
598 }
599 while ( pWin );
600
601 return false;
602}
603
604IMPL_LINK_NOARG(FloatingWindow, ImplEndPopupModeHdl, void*, void)void FloatingWindow::LinkStubImplEndPopupModeHdl(void * instance
, void* data) { return static_cast<FloatingWindow *>(instance
)->ImplEndPopupModeHdl(data); } void FloatingWindow::ImplEndPopupModeHdl
(__attribute__ ((unused)) void*)
605{
606 VclPtr<FloatingWindow> pThis(this);
607 mnPostId = nullptr;
608 mnPopupModeFlags = FloatWinPopupFlags::NONE;
609 mbPopupMode = false;
610 PopupModeEnd();
611}
612
613bool FloatingWindow::EventNotify( NotifyEvent& rNEvt )
614{
615 // call Base Class first for tab control
616 bool bRet = SystemWindow::EventNotify( rNEvt );
617 if ( !bRet )
618 {
619 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
620 {
621 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
622 vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
623 sal_uInt16 nKeyCode = aKeyCode.GetCode();
624
625 if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
626 {
627 Close();
628 return true;
629 }
630 }
631 }
632
633 return bRet;
634}
635
636void FloatingWindow::PixelInvalidate(const tools::Rectangle* /*pRectangle*/)
637{
638 if (VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier())
639 {
640 std::vector<vcl::LOKPayloadItem> aPayload;
641 const tools::Rectangle aRect(Point(0,0), Size(GetSizePixel().Width()+1, GetSizePixel().Height()+1));
642 aPayload.push_back(std::make_pair(OString("rectangle"), aRect.toString()));
643 const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier();
644 pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
645 }
646}
647
648void FloatingWindow::StateChanged( StateChangedType nType )
649{
650 if (nType == StateChangedType::InitShow)
651 {
652 DoInitialLayout();
653 }
654
655 SystemWindow::StateChanged( nType );
656
657 VclPtr<vcl::Window> pParent = GetParentWithLOKNotifier();
658 if (pParent)
659 {
660 if (nType == StateChangedType::InitShow)
661 {
662 std::vector<vcl::LOKPayloadItem> aItems;
663 if (pParent == this)
664 {
665 // we are a toplevel window, let's so far pretend to be a
666 // dialog - but maybe we'll need a separate type for this
667 // later
668 aItems.emplace_back("type", "dialog");
669 aItems.emplace_back("position", mpImplData->maLOKTwipsPos.toString()); // twips
670 }
671 else
672 {
673 SetLOKNotifier(pParent->GetLOKNotifier());
674 if (dynamic_cast<HelpTextWindow*>(this))
675 aItems.emplace_back("type", "tooltip");
676 else
677 aItems.emplace_back("type", "child");
678
679 aItems.emplace_back("parentId", OString::number(pParent->GetLOKWindowId()));
680 if (mbInPopupMode)
681 aItems.emplace_back("position", mpImplData->maPos.toString()); // pixels
682 else // mpImplData->maPos is not set
683 aItems.emplace_back("position", GetPosPixel().toString());
684
685 }
686 aItems.emplace_back("size", GetSizePixel().toString());
687 GetLOKNotifier()->notifyWindow(GetLOKWindowId(), "created", aItems);
688 }
689 else if (!IsVisible() && nType == StateChangedType::Visible)
690 {
691 if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
692 {
693 pNotifier->notifyWindow(GetLOKWindowId(), "close");
694 ReleaseLOKNotifier();
695 }
696 }
697 }
698
699 if ( nType == StateChangedType::ControlBackground )
700 {
701 ImplInitSettings();
702 Invalidate();
703 }
704}
705
706void FloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
707{
708 SystemWindow::DataChanged( rDCEvt );
709
710 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
711 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
712 {
713 ImplInitSettings();
714 Invalidate();
715 }
716}
717
718void FloatingWindow::ImplCallPopupModeEnd()
719{
720 // PopupMode is finished
721 mbInPopupMode = false;
722
723 // call Handler asynchronously.
724 if ( mpImplData && !mnPostId )
725 mnPostId = Application::PostUserEvent(LINK(this, FloatingWindow, ImplEndPopupModeHdl)::tools::detail::makeLink( ::tools::detail::castTo<FloatingWindow
*>(this), &FloatingWindow::LinkStubImplEndPopupModeHdl
)
);
726}
727
728void FloatingWindow::PopupModeEnd()
729{
730 maPopupModeEndHdl.Call( this );
731}
732
733void FloatingWindow::SetTitleType( FloatWinTitleType nTitle )
734{
735 if ( (mnTitle == nTitle) || !mpWindowImpl->mpBorderWindow )
736 return;
737
738 mnTitle = nTitle;
739 Size aOutSize = GetOutputSizePixel();
740 BorderWindowTitleType nTitleStyle;
741 if ( nTitle == FloatWinTitleType::Normal )
742 nTitleStyle = BorderWindowTitleType::Small;
743 else if ( nTitle == FloatWinTitleType::TearOff )
744 nTitleStyle = BorderWindowTitleType::Tearoff;
745 else if ( nTitle == FloatWinTitleType::Popup )
746 nTitleStyle = BorderWindowTitleType::Popup;
747 else // nTitle == FloatWinTitleType::NONE
748 nTitleStyle = BorderWindowTitleType::NONE;
749 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetTitleType( nTitleStyle, aOutSize );
750 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
751}
752
753void FloatingWindow::StartPopupMode( const tools::Rectangle& rRect, FloatWinPopupFlags nFlags )
754{
755 if ( IsRollUp() )
756 RollDown();
757
758 // remove title
759 mnOldTitle = mnTitle;
760 if ( ( mpWindowImpl->mnStyle & WB_POPUP ) && !GetText().isEmpty() )
761 SetTitleType( FloatWinTitleType::Popup );
762 else if ( nFlags & FloatWinPopupFlags::AllowTearOff )
763 SetTitleType( FloatWinTitleType::TearOff );
764 else
765 SetTitleType( FloatWinTitleType::NONE );
766
767 // avoid close on focus change for decorated floating windows only
768 if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
769 nFlags |= FloatWinPopupFlags::NoAppFocusClose;
770
771 // compute window position according to flags and arrangement
772 sal_uInt16 nArrangeIndex;
773 DoInitialLayout();
774 mpImplData->maPos = ImplCalcPos(this, rRect, nFlags, nArrangeIndex, &mpImplData->maLOKTwipsPos);
775 SetPosPixel( mpImplData->maPos );
776 ImplGetFrame()->PositionByToolkit(rRect, nFlags);
777
778 // set data and display window
779 // convert maFloatRect to absolute device coordinates
780 // so they can be compared across different frames
781 // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
782 maFloatRect = FloatingWindow::ImplConvertToAbsPos(GetParent(), rRect);
783
784 maFloatRect.AdjustLeft( -2 );
785 maFloatRect.AdjustTop( -2 );
786 maFloatRect.AdjustRight(2 );
787 maFloatRect.AdjustBottom(2 );
788 mnPopupModeFlags = nFlags;
789 mbInPopupMode = true;
790 mbPopupMode = true;
791 mbPopupModeCanceled = false;
792 mbPopupModeTearOff = false;
793 mbMouseDown = false;
794
795 // add FloatingWindow to list of windows that are in popup mode
796 ImplSVData* pSVData = ImplGetSVData();
797 mpNextFloat = pSVData->mpWinData->mpFirstFloat;
798 pSVData->mpWinData->mpFirstFloat = this;
799 if (nFlags & FloatWinPopupFlags::GrabFocus)
800 {
801 // force key input even without focus (useful for menus)
802 mbGrabFocus = true;
803 mxPrevFocusWin = Window::SaveFocus();
804 mpWindowImpl->mpFrameData->mbHasFocus = true;
805 GrabFocus();
806 }
807 Show( true, ShowFlags::NoActivate );
808}
809
810void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags )
811{
812 mpImplData->mpBox = pBox;
813
814 // get selected button
815 sal_uInt16 nItemId = pBox->GetDownItemId();
816
817 if ( nItemId )
818 pBox->ImplFloatControl( true, this );
819
820 // retrieve some data from the ToolBox
821 tools::Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect();
822
823 // convert to parent's screen coordinates
824 mpImplData->maPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
825 aRect.SetPos( mpImplData->maPos );
826
827 nFlags |=
828 FloatWinPopupFlags::AllMouseButtonClose |
829 FloatWinPopupFlags::NoMouseUpClose;
830
831 // set Flags for positioning
832 if ( !(nFlags & (FloatWinPopupFlags::Down | FloatWinPopupFlags::Up |
833 FloatWinPopupFlags::Left | FloatWinPopupFlags::Right)) )
834 {
835 if ( pBox->IsHorizontal() )
836 nFlags |= FloatWinPopupFlags::Down;
837 else
838 nFlags |= FloatWinPopupFlags::Right;
839 }
840
841 // start FloatingMode
842 StartPopupMode( aRect, nFlags );
843}
844
845void FloatingWindow::ImplEndPopupMode( FloatWinPopupEndFlags nFlags, const VclPtr<vcl::Window>& xFocusId )
846{
847 if ( !mbInPopupMode )
8
Assuming field 'mbInPopupMode' is true
9
Taking false branch
848 return;
849
850 ImplSVData* pSVData = ImplGetSVData();
851
852 mbInCleanUp = true; // prevent killing this window due to focus change while working with it
853
854 if (!(nFlags & FloatWinPopupEndFlags::NoCloseChildren))
10
Taking true branch
855 {
856 // stop the PopupMode also for all PopupMode windows created after us
857 std::vector<VclPtr<FloatingWindow>> aCancelFloats;
858 // stop the PopupMode also for all following PopupMode windows
859 for (auto pFloat = pSVData->mpWinData->mpFirstFloat;
11
Calling implicit copy constructor for 'VclPtr<FloatingWindow>'
12
Calling copy constructor for 'Reference<FloatingWindow>'
15
Returning from copy constructor for 'Reference<FloatingWindow>'
16
Returning from copy constructor for 'VclPtr<FloatingWindow>'
17
Loop condition is false. Execution continues on line 112
860 pFloat != nullptr && pFloat != this;
861 pFloat = pFloat->mpNextFloat)
862 aCancelFloats.push_back(pFloat);
18
Calling implicit destructor for 'VclPtr<FloatingWindow>'
19
Calling '~Reference'
26
Returning from '~Reference'
27
Returning from destructor for 'VclPtr<FloatingWindow>'
863 for (auto & it : aCancelFloats)
864 it->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::NoCloseChildren);
865 }
866
867 // delete window from the list
868 pSVData->mpWinData->mpFirstFloat = mpNextFloat;
28
Calling implicit copy assignment operator for 'VclPtr<FloatingWindow>'
29
Calling copy assignment operator for 'Reference<FloatingWindow>'
869 mpNextFloat = nullptr;
870
871 FloatWinPopupFlags nPopupModeFlags = mnPopupModeFlags;
872 mbPopupModeTearOff = nFlags & FloatWinPopupEndFlags::TearOff &&
873 nPopupModeFlags & FloatWinPopupFlags::AllowTearOff;
874
875 // hide window again if it was not deleted
876 if (!mbPopupModeTearOff)
877 Show( false, ShowFlags::NoFocusChange );
878
879 if (HasChildPathFocus() && xFocusId != nullptr)
880 {
881 // restore focus to previous focus window if we still have the focus
882 Window::EndSaveFocus(xFocusId);
883 }
884 else if ( pSVData->mpWinData->mpFocusWin && pSVData->mpWinData->mpFirstFloat &&
885 ImplIsWindowOrChild( pSVData->mpWinData->mpFocusWin ) )
886 {
887 // maybe pass focus on to a suitable FloatingWindow
888 pSVData->mpWinData->mpFirstFloat->GrabFocus();
889 }
890
891 mbPopupModeCanceled = bool(nFlags & FloatWinPopupEndFlags::Cancel);
892
893 // redo title
894 SetTitleType( mnOldTitle );
895
896 // set ToolBox again to normal
897 if (mpImplData && mpImplData->mpBox)
898 {
899 mpImplData->mpBox->ImplFloatControl( false, this );
900 // if the parent ToolBox is in popup mode, it should be closed too.
901 if ( GetDockingManager()->IsInPopupMode( mpImplData->mpBox ) )
902 nFlags |= FloatWinPopupEndFlags::CloseAll;
903
904 mpImplData->mpBox = nullptr;
905 }
906
907 // call PopupModeEnd-Handler depending on parameter
908 if ( !(nFlags & FloatWinPopupEndFlags::DontCallHdl) )
909 ImplCallPopupModeEnd();
910
911 // close all other windows depending on parameter
912 if ( nFlags & FloatWinPopupEndFlags::CloseAll )
913 {
914 if ( !(nPopupModeFlags & FloatWinPopupFlags::NewLevel) )
915 {
916 if (pSVData->mpWinData->mpFirstFloat)
917 {
918 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
919 pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
920 }
921 }
922 }
923
924 mbInCleanUp = false;
925}
926
927void FloatingWindow::EndPopupMode( FloatWinPopupEndFlags nFlags )
928{
929 ImplEndPopupMode(nFlags, mxPrevFocusWin);
7
Calling 'FloatingWindow::ImplEndPopupMode'
930}
931
932void FloatingWindow::AddPopupModeWindow(vcl::Window* pWindow)
933{
934 // !!! up-to-now only 1 window and not yet a list
935 mpFirstPopupModeWin = pWindow;
936}
937bool FloatingWindow::UpdatePositionData()
938{
939 auto pWin = ImplGetParent();
940 if (pWin)
941 {
942 // Simulate Move, so the relative position of the floating window will be recalculated
943 pWin->ImplCallMove();
944 return true;
945 }
946
947 return false;
948}
949
950/* 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)
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)
13
Assuming field 'm_pBody' is non-null
14
Taking true branch
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
19.1
Field 'm_pBody' is non-null
19.1
Field 'm_pBody' is non-null
19.1
Field 'm_pBody' is non-null
)
20
Taking true branch
113 m_pBody->release();
21
Calling 'VclReferenceBase::release'
25
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)
31
Assuming 'pBody' is null
32
Taking false branch
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld
32.1
'pOld' is non-null
32.1
'pOld' is non-null
32.1
'pOld' is non-null
)
33
Taking true branch
127 pOld->release();
34
Use of memory after it is freed
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 );
30
Calling 'Reference::set'
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)
22
Assuming the condition is true
23
Taking true branch
40 delete this;
24
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