Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
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 pagepreviewlayout.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 /usr/include/libxml2 -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 SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -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/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -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/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -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/UnoApiHeadersTarget/oovbaapi/normal -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/sw/source/core/view/pagepreviewlayout.cxx

/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.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 <pagepreviewlayout.hxx>
21#include <prevwpage.hxx>
22
23#include <algorithm>
24#include <tools/fract.hxx>
25#include <vcl/window.hxx>
26#include <vcl/settings.hxx>
27
28#include <rootfrm.hxx>
29#include <pagefrm.hxx>
30#include <viewsh.hxx>
31#include <viewimp.hxx>
32#include <viewopt.hxx>
33#include <swregion.hxx>
34#include <strings.hrc>
35#include <frmtool.hxx>
36#include <sfx2/zoomitem.hxx>
37#include <printdata.hxx>
38#include <paintfrm.hxx>
39
40#include <IDocumentDeviceAccess.hxx>
41
42// methods to initialize page preview layout
43
44SwPagePreviewLayout::SwPagePreviewLayout( SwViewShell& _rParentViewShell,
45 const SwRootFrame& _rLayoutRootFrame )
46 : mrParentViewShell( _rParentViewShell ),
47 mrLayoutRootFrame ( _rLayoutRootFrame )
48{
49 Clear_();
50
51 mbBookPreview = false;
52 mbBookPreviewModeToggled = false;
53
54 mbPrintEmptyPages = mrParentViewShell.getIDocumentDeviceAccess().getPrintData().IsPrintEmptyPages();
55}
56
57void SwPagePreviewLayout::Clear_()
58{
59 mbLayoutInfoValid = mbLayoutSizesValid = mbPaintInfoValid = false;
60
61 maWinSize.setWidth( 0 );
62 maWinSize.setHeight( 0 );
63 mnCols = mnRows = 0;
64
65 ClearPreviewLayoutSizes();
66
67 mbDoesLayoutRowsFitIntoWindow = false;
68 mbDoesLayoutColsFitIntoWindow = false;
69
70 mnPaintPhyStartPageNum = 0;
71 mnPaintStartCol = mnPaintStartRow = 0;
72 mbNoPageVisible = false;
73 maPaintStartPageOffset.setX( 0 );
74 maPaintStartPageOffset.setY( 0 );
75 maPaintPreviewDocOffset.setX( 0 );
76 maPaintPreviewDocOffset.setY( 0 );
77 maAdditionalPaintOffset.setX( 0 );
78 maAdditionalPaintOffset.setY( 0 );
79 maPaintedPreviewDocRect.SetLeft( 0 );
80 maPaintedPreviewDocRect.SetTop( 0 );
81 maPaintedPreviewDocRect.SetRight( 0 );
82 maPaintedPreviewDocRect.SetBottom( 0 );
83 mnSelectedPageNum = 0;
84 ClearPreviewPageData();
85
86 mbInPaint = false;
87 mbNewLayoutDuringPaint = false;
88}
89
90void SwPagePreviewLayout::ClearPreviewLayoutSizes()
91{
92 mnPages = 0;
93
94 maMaxPageSize.setWidth( 0 );
95 maMaxPageSize.setHeight( 0 );
96 maPreviewDocRect.SetLeft( 0 );
97 maPreviewDocRect.SetTop( 0 );
98 maPreviewDocRect.SetRight( 0 );
99 maPreviewDocRect.SetBottom( 0 );
100 mnColWidth = mnRowHeight = 0;
101 mnPreviewLayoutWidth = mnPreviewLayoutHeight = 0;
102}
103
104void SwPagePreviewLayout::ClearPreviewPageData()
105{
106 maPreviewPages.clear();
107}
108
109/** calculate page preview layout sizes
110
111*/
112void SwPagePreviewLayout::CalcPreviewLayoutSizes()
113{
114 vcl::RenderContext* pRenderContext = mrParentViewShell.GetOut();
115 // calculate maximal page size; calculate also number of pages
116
117 const SwPageFrame* pPage = static_cast<const SwPageFrame*>(mrLayoutRootFrame.Lower());
118 while ( pPage )
119 {
120 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
121 {
122 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
123 continue;
124 }
125
126 ++mnPages;
127 pPage->Calc(pRenderContext);
128 const Size& rPageSize = pPage->getFrameArea().SSize();
129 if ( rPageSize.Width() > maMaxPageSize.Width() )
130 maMaxPageSize.setWidth( rPageSize.Width() );
131 if ( rPageSize.Height() > maMaxPageSize.Height() )
132 maMaxPageSize.setHeight( rPageSize.Height() );
133 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
134 }
135 // calculate and set column width and row height
136 mnColWidth = maMaxPageSize.Width() + gnXFree;
137 mnRowHeight = maMaxPageSize.Height() + gnYFree;
138
139 // calculate and set preview layout width and height
140 mnPreviewLayoutWidth = mnCols * mnColWidth + gnXFree;
141 mnPreviewLayoutHeight = mnRows * mnRowHeight + gnYFree;
142
143 // calculate document rectangle in preview layout
144 {
145 Size aDocSize;
146 // document width
147 aDocSize.setWidth( mnPreviewLayoutWidth );
148
149 // document height
150 // determine number of rows needed for <nPages> in preview layout
151 // use method <GetRowOfPage(..)>.
152 const sal_uInt16 nDocRows = GetRowOfPage( mnPages );
153 aDocSize.setHeight( nDocRows * maMaxPageSize.Height() +
154 (nDocRows+1) * gnYFree );
155 maPreviewDocRect.SetPos( Point( 0, 0 ) );
156 maPreviewDocRect.SetSize( aDocSize );
157 }
158}
159
160/** init page preview layout
161
162 initialize the page preview settings for a given layout.
163
164 side effects:
165 (1) If parameter <_bCalcScale> is true, mapping mode with calculated
166 scaling is set at the output device and the zoom at the view options of
167 the given view shell is set with the calculated scaling.
168*/
169void SwPagePreviewLayout::Init( const sal_uInt16 _nCols,
170 const sal_uInt16 _nRows,
171 const Size& _rPxWinSize
172 )
173{
174 // check environment and parameters
175 {
176 bool bColsRowsValid = (_nCols != 0) && (_nRows != 0);
177 OSL_ENSURE( bColsRowsValid, "preview layout parameters not correct - preview layout can *not* be initialized" )do { if (true && (!(bColsRowsValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "177" ": "), "%s", "preview layout parameters not correct - preview layout can *not* be initialized"
); } } while (false)
;
178 if ( !bColsRowsValid )
179 return;
180
181 bool bPxWinSizeValid = (_rPxWinSize.Width() >= 0) &&
182 (_rPxWinSize.Height() >= 0);
183 OSL_ENSURE( bPxWinSizeValid, "no window size - preview layout can *not* be initialized" )do { if (true && (!(bPxWinSizeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "183" ": "), "%s", "no window size - preview layout can *not* be initialized"
); } } while (false)
;
184 if ( !bPxWinSizeValid )
185 return;
186 }
187
188 // environment and parameters ok
189
190 // clear existing preview settings
191 Clear_();
192
193 // set layout information columns and rows
194 mnCols = _nCols;
195 mnRows = _nRows;
196
197 CalcPreviewLayoutSizes();
198
199 // validate layout information
200 mbLayoutInfoValid = true;
201
202 // calculate scaling
203 MapMode aMapMode( MapUnit::MapTwip );
204 Size aWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize, aMapMode );
205 Fraction aXScale( aWinSize.Width(), mnPreviewLayoutWidth );
206 Fraction aYScale( aWinSize.Height(), mnPreviewLayoutHeight );
207 if( aXScale < aYScale )
208 aYScale = aXScale;
209 {
210 // adjust scaling for Drawing layer.
211 aYScale *= Fraction( 1000, 1 );
212 long nNewNuminator = aYScale.operator long();
213 if( nNewNuminator < 1 )
214 nNewNuminator = 1;
215 aYScale = Fraction( nNewNuminator, 1000 );
216 // propagate scaling as zoom percentage to view options for font cache
217 ApplyNewZoomAtViewShell( static_cast<sal_uInt8>(nNewNuminator/10) );
218
219 aMapMode.SetScaleY( aYScale );
220 aMapMode.SetScaleX( aYScale );
221 // set created mapping mode with calculated scaling at output device.
222 mrParentViewShell.GetOut()->SetMapMode( aMapMode );
223 // update statics for paint.
224 ::SwCalcPixStatics( mrParentViewShell.GetOut() );
225 }
226
227 // set window size in twips
228 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
229 // validate layout sizes
230 mbLayoutSizesValid = true;
231}
232
233/** apply new zoom at given view shell */
234void SwPagePreviewLayout::ApplyNewZoomAtViewShell( sal_uInt8 _aNewZoom )
235{
236 SwViewOption aNewViewOptions = *(mrParentViewShell.GetViewOptions());
237 if ( aNewViewOptions.GetZoom() != _aNewZoom )
238 {
239 aNewViewOptions.SetZoom( _aNewZoom );
240 //#i19975# - consider zoom type.
241 aNewViewOptions.SetZoomType( SvxZoomType::PERCENT );
242 mrParentViewShell.ApplyViewOptions( aNewViewOptions );
243 }
244}
245
246/** method to adjust page preview layout to document changes
247
248*/
249void SwPagePreviewLayout::ReInit()
250{
251 // check environment and parameters
252 {
253 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
254 OSL_ENSURE( bLayoutSettingsValid,do { if (true && (!(bLayoutSettingsValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "255" ": "), "%s", "no valid preview layout info/sizes - no re-init of page preview layout"
); } } while (false)
255 "no valid preview layout info/sizes - no re-init of page preview layout")do { if (true && (!(bLayoutSettingsValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "255" ": "), "%s", "no valid preview layout info/sizes - no re-init of page preview layout"
); } } while (false)
;
256 if ( !bLayoutSettingsValid )
257 return;
258 }
259
260 ClearPreviewLayoutSizes();
261 CalcPreviewLayoutSizes();
262}
263
264// methods to prepare paint of page preview
265
266/** prepare paint of page preview
267
268 delete parameter _onStartPageVirtNum
269
270 @note _nProposedStartPageNum, _onStartPageNum are absolute
271*/
272bool SwPagePreviewLayout::Prepare( const sal_uInt16 _nProposedStartPageNum,
273 const Point& rProposedStartPos,
274 const Size& _rPxWinSize,
275 sal_uInt16& _onStartPageNum,
276 tools::Rectangle& _orDocPreviewPaintRect,
277 const bool _bStartWithPageAtFirstCol
278 )
279{
280 sal_uInt16 nProposedStartPageNum = ConvertAbsoluteToRelativePageNum( _nProposedStartPageNum );
281 // check environment and parameters
282 {
283 bool bLayoutSettingsValid = mbLayoutInfoValid && mbLayoutSizesValid;
284 OSL_ENSURE( bLayoutSettingsValid,do { if (true && (!(bLayoutSettingsValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "285" ": "), "%s", "no valid preview layout info/sizes - no prepare of preview paint"
); } } while (false)
285 "no valid preview layout info/sizes - no prepare of preview paint")do { if (true && (!(bLayoutSettingsValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "285" ": "), "%s", "no valid preview layout info/sizes - no prepare of preview paint"
); } } while (false)
;
286 if ( !bLayoutSettingsValid )
287 return false;
288
289 bool bStartPageRangeValid = nProposedStartPageNum <= mnPages;
290 OSL_ENSURE( bStartPageRangeValid,do { if (true && (!(bStartPageRangeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "291" ": "), "%s", "proposed start page not existing - no prepare of preview paint"
); } } while (false)
291 "proposed start page not existing - no prepare of preview paint")do { if (true && (!(bStartPageRangeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "291" ": "), "%s", "proposed start page not existing - no prepare of preview paint"
); } } while (false)
;
292 if ( !bStartPageRangeValid )
293 return false;
294
295 bool bStartPosRangeValid =
296 rProposedStartPos.X() >= 0 && rProposedStartPos.Y() >= 0 &&
297 rProposedStartPos.X() <= maPreviewDocRect.Right() &&
298 rProposedStartPos.Y() <= maPreviewDocRect.Bottom();
299 OSL_ENSURE( bStartPosRangeValid,do { if (true && (!(bStartPosRangeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "300" ": "), "%s", "proposed start position out of range - no prepare of preview paint"
); } } while (false)
300 "proposed start position out of range - no prepare of preview paint")do { if (true && (!(bStartPosRangeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "300" ": "), "%s", "proposed start position out of range - no prepare of preview paint"
); } } while (false)
;
301 if ( !bStartPosRangeValid )
302 return false;
303
304 bool bWinSizeValid = !_rPxWinSize.IsEmpty();
305 OSL_ENSURE( bWinSizeValid, "no window size - no prepare of preview paint")do { if (true && (!(bWinSizeValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "305" ": "), "%s", "no window size - no prepare of preview paint"
); } } while (false)
;
306 if ( !bWinSizeValid )
307 return false;
308
309 bool bStartInfoValid = _nProposedStartPageNum > 0 ||
310 rProposedStartPos != Point(0,0);
311 if ( !bStartInfoValid )
312 nProposedStartPageNum = 1;
313 }
314
315 // environment and parameter ok
316
317 // update window size at preview setting data
318 maWinSize = mrParentViewShell.GetOut()->PixelToLogic( _rPxWinSize );
319
320 mbNoPageVisible = false;
321 if ( nProposedStartPageNum > 0 )
322 {
323 // determine column and row of proposed start page in virtual preview layout
324 const sal_uInt16 nColOfProposed = GetColOfPage( nProposedStartPageNum );
325 const sal_uInt16 nRowOfProposed = GetRowOfPage( nProposedStartPageNum );
326 // determine start page
327 if ( _bStartWithPageAtFirstCol )
328 {
329 // leaving left-top-corner blank is
330 // controlled by <mbBookPreview>.
331 if ( mbBookPreview &&
332 ( nProposedStartPageNum == 1 || nRowOfProposed == 1 )
333 )
334 mnPaintPhyStartPageNum = 1;
335 else
336 mnPaintPhyStartPageNum = nProposedStartPageNum - (nColOfProposed-1);
337 }
338 else
339 mnPaintPhyStartPageNum = nProposedStartPageNum;
340
341 mnPaintPhyStartPageNum = ConvertRelativeToAbsolutePageNum( mnPaintPhyStartPageNum );
342
343 // set starting column
344 if ( _bStartWithPageAtFirstCol )
345 mnPaintStartCol = 1;
346 else
347 mnPaintStartCol = nColOfProposed;
348 // set starting row
349 mnPaintStartRow = nRowOfProposed;
350 // page offset == (-1,-1), indicating no offset and paint of free space.
351 maPaintStartPageOffset.setX( -1 );
352 maPaintStartPageOffset.setY( -1 );
353 // virtual preview document offset.
354 if ( _bStartWithPageAtFirstCol )
355 maPaintPreviewDocOffset.setX( 0 );
356 else
357 maPaintPreviewDocOffset.setX( (nColOfProposed-1) * mnColWidth );
358 maPaintPreviewDocOffset.setY( (nRowOfProposed-1) * mnRowHeight );
359 }
360 else
361 {
362 // determine column and row of proposed start position.
363 // Note: paint starts at point (0,0)
364 const sal_uInt16 nColOfProposed =
365 static_cast<sal_uInt16>(rProposedStartPos.X() / mnColWidth) + 1;
366 const sal_uInt16 nRowOfProposed =
367 static_cast<sal_uInt16>(rProposedStartPos.Y() / mnRowHeight) + 1;
368 // determine start page == page at proposed start position
369 // leaving left-top-corner blank is
370 // controlled by <mbBookPreview>.
371 if ( mbBookPreview &&
372 ( nRowOfProposed == 1 && nColOfProposed == 1 )
373 )
374 mnPaintPhyStartPageNum = 1;
375 else
376 {
377 // leaving left-top-corner blank is
378 // controlled by <mbBookPreview>.
379 mnPaintPhyStartPageNum = (nRowOfProposed-1) * mnCols + nColOfProposed;
380 if ( mbBookPreview )
381 --mnPaintPhyStartPageNum;
382 if ( mnPaintPhyStartPageNum > mnPages )
383 {
384 // no page will be visible, because shown part of document
385 // preview is the last row to the right of the last page
386 mnPaintPhyStartPageNum = mnPages;
387 mbNoPageVisible = true;
388 }
389 }
390 // set starting column and starting row
391 mnPaintStartCol = nColOfProposed;
392 mnPaintStartRow = nRowOfProposed;
393 // page offset
394 maPaintStartPageOffset.setX(
395 (rProposedStartPos.X() % mnColWidth) - gnXFree );
396 maPaintStartPageOffset.setY(
397 (rProposedStartPos.Y() % mnRowHeight) - gnYFree );
398 // virtual preview document offset.
399 maPaintPreviewDocOffset = rProposedStartPos;
400 }
401
402 // determine additional paint offset, if preview layout fits into window.
403 CalcAdditionalPaintOffset();
404
405 // determine rectangle to be painted from document preview
406 CalcDocPreviewPaintRect();
407 _orDocPreviewPaintRect = maPaintedPreviewDocRect;
408
409 // shift visible preview document area to the left,
410 // if on the right is an area left blank.
411 if ( !mbDoesLayoutColsFitIntoWindow &&
412 maPaintedPreviewDocRect.GetWidth() < maWinSize.Width() )
413 {
414 maPaintedPreviewDocRect.Move(
415 -(maWinSize.Width() - maPaintedPreviewDocRect.GetWidth()), 0 );
416 Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
417 _rPxWinSize, _onStartPageNum,
418 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
419 }
420
421 // shift visible preview document area to the top,
422 // if on the bottom is an area left blank.
423 if ( mbBookPreviewModeToggled &&
424 maPaintedPreviewDocRect.Bottom() == maPreviewDocRect.Bottom() &&
425 maPaintedPreviewDocRect.GetHeight() < maWinSize.Height() )
426 {
427 if ( mbDoesLayoutRowsFitIntoWindow )
428 {
429 if ( maPaintedPreviewDocRect.GetHeight() < mnPreviewLayoutHeight)
430 {
431 maPaintedPreviewDocRect.Move(
432 0, -(mnPreviewLayoutHeight - maPaintedPreviewDocRect.GetHeight()) );
433 Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
434 _rPxWinSize, _onStartPageNum,
435 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
436 }
437 }
438 else
439 {
440 maPaintedPreviewDocRect.Move(
441 0, -(maWinSize.Height() - maPaintedPreviewDocRect.GetHeight()) );
442 Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
443 _rPxWinSize, _onStartPageNum,
444 _orDocPreviewPaintRect, _bStartWithPageAtFirstCol );
445 }
446 }
447
448 // determine preview pages - visible pages with needed data for paint and
449 // accessible pages with needed data.
450 CalcPreviewPages();
451
452 // OD 07.11.2003 #i22014# - indicate new layout, if print preview is in paint
453 if ( mbInPaint )
454 {
455 mbNewLayoutDuringPaint = true;
456 }
457
458 // validate paint data
459 mbPaintInfoValid = true;
460
461 // return start page
462 _onStartPageNum = mnPaintPhyStartPageNum;
463
464 return true;
465}
466
467/** calculate additional paint offset
468
469*/
470void SwPagePreviewLayout::CalcAdditionalPaintOffset()
471{
472 if ( mnPreviewLayoutWidth <= maWinSize.Width() &&
473 maPaintStartPageOffset.X() <= 0 )
474 {
475 mbDoesLayoutColsFitIntoWindow = true;
476 maAdditionalPaintOffset.setX( (maWinSize.Width() - mnPreviewLayoutWidth) / 2 );
477 }
478 else
479 {
480 mbDoesLayoutColsFitIntoWindow = false;
481 maAdditionalPaintOffset.setX( 0 );
482 }
483
484 if ( mnPreviewLayoutHeight <= maWinSize.Height() &&
485 maPaintStartPageOffset.Y() <= 0 )
486 {
487 mbDoesLayoutRowsFitIntoWindow = true;
488 maAdditionalPaintOffset.setY( (maWinSize.Height() - mnPreviewLayoutHeight) / 2 );
489 }
490 else
491 {
492 mbDoesLayoutRowsFitIntoWindow = false;
493 maAdditionalPaintOffset.setY( 0 );
494 }
495}
496
497/** calculate painted preview document rectangle
498
499*/
500void SwPagePreviewLayout::CalcDocPreviewPaintRect()
501{
502 Point aTopLeftPos = maPaintPreviewDocOffset;
503 maPaintedPreviewDocRect.SetPos( aTopLeftPos );
504
505 Size aSize;
506 if ( mbDoesLayoutColsFitIntoWindow )
507 aSize.setWidth( std::min( mnPreviewLayoutWidth,
508 maPreviewDocRect.GetWidth() - aTopLeftPos.X() ) );
509 else
510 aSize.setWidth( std::min( maPreviewDocRect.GetWidth() - aTopLeftPos.X(),
511 maWinSize.Width() - maAdditionalPaintOffset.X() ) );
512 if ( mbDoesLayoutRowsFitIntoWindow )
513 aSize.setHeight( std::min( mnPreviewLayoutHeight,
514 maPreviewDocRect.GetHeight() - aTopLeftPos.Y() ) );
515 else
516 aSize.setHeight( std::min( maPreviewDocRect.GetHeight() - aTopLeftPos.Y(),
517 maWinSize.Height() - maAdditionalPaintOffset.Y() ) );
518 maPaintedPreviewDocRect.SetSize( aSize );
519}
520
521/** calculate preview pages
522
523*/
524void SwPagePreviewLayout::CalcPreviewPages()
525{
526 vcl::RenderContext* pRenderContext = mrParentViewShell.GetOut();
527 ClearPreviewPageData();
528
529 if ( mbNoPageVisible )
530 return;
531
532 // determine start page frame
533 const SwPageFrame* pStartPage = mrLayoutRootFrame.GetPageByPageNum( mnPaintPhyStartPageNum );
534
535 // calculate initial paint offset
536 Point aInitialPaintOffset;
537 /// check whether RTL interface or not
538 if(!AllSettings::GetLayoutRTL()){
539 if ( maPaintStartPageOffset != Point( -1, -1 ) )
540 aInitialPaintOffset = Point(0,0) - maPaintStartPageOffset;
541 else
542 aInitialPaintOffset = Point( gnXFree, gnYFree );
543 }
544 else {
545 if ( maPaintStartPageOffset != Point( -1, -1 ) )
546 aInitialPaintOffset = Point(0 + ((SwPagePreviewLayout::mnCols-1)*mnColWidth),0) - maPaintStartPageOffset;
547 else
548 aInitialPaintOffset = Point( gnXFree + ((SwPagePreviewLayout::mnCols-1)*mnColWidth), gnYFree );
549 }
550 aInitialPaintOffset += maAdditionalPaintOffset;
551
552 // prepare loop data
553 const SwPageFrame* pPage = pStartPage;
554 sal_uInt16 nCurrCol = mnPaintStartCol;
555 sal_uInt16 nConsideredRows = 0;
556 Point aCurrPaintOffset = aInitialPaintOffset;
557 // loop on pages to determine preview background rectangles
558 while ( pPage &&
559 (!mbDoesLayoutRowsFitIntoWindow || nConsideredRows < mnRows) &&
560 aCurrPaintOffset.Y() < maWinSize.Height()
561 )
562 {
563 if ( !mbBookPreview && !mbPrintEmptyPages && pPage->IsEmptyPage() )
564 {
565 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
566 continue;
567 }
568
569 pPage->Calc(pRenderContext);
570
571 // consider only pages, which have to be painted.
572 if ( nCurrCol < mnPaintStartCol )
573 {
574 // calculate data of unvisible page needed for accessibility
575 std::unique_ptr<PreviewPage> pPreviewPage(new PreviewPage);
576 Point aCurrAccOffset = aCurrPaintOffset -
577 Point( (mnPaintStartCol-nCurrCol) * mnColWidth, 0 );
578 CalcPreviewDataForPage( *pPage, aCurrAccOffset, pPreviewPage.get() );
579 pPreviewPage->bVisible = false;
580 maPreviewPages.push_back( std::move(pPreviewPage) );
581 // continue with next page and next column
582 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
583 ++nCurrCol;
584 continue;
585 }
586 if ( aCurrPaintOffset.X() < maWinSize.Width() )
587 {
588 // leaving left-top-corner blank is
589 // controlled by <mbBookPreview>.
590 if ( mbBookPreview && pPage->GetPhyPageNum() == 1 && mnCols != 1 && nCurrCol == 1
591 )
592 {
593 // first page in 2nd column
594 // --> continue with increased paint offset and next column
595 /// check whether RTL interface or not
596 if(!AllSettings::GetLayoutRTL())
597 aCurrPaintOffset.AdjustX(mnColWidth );
598 else aCurrPaintOffset.AdjustX( -mnColWidth );
599 ++nCurrCol;
600 continue;
601 }
602
603 // calculate data of visible page
604 std::unique_ptr<PreviewPage> pPreviewPage(new PreviewPage);
605 CalcPreviewDataForPage( *pPage, aCurrPaintOffset, pPreviewPage.get() );
606 pPreviewPage->bVisible = true;
607 maPreviewPages.push_back( std::move(pPreviewPage) );
608 }
609 else
610 {
611 // calculate data of unvisible page needed for accessibility
612 std::unique_ptr<PreviewPage> pPreviewPage(new PreviewPage);
613 CalcPreviewDataForPage( *pPage, aCurrPaintOffset, pPreviewPage.get() );
614 pPreviewPage->bVisible = false;
615 maPreviewPages.push_back( std::move(pPreviewPage) );
616 }
617
618 // prepare data for next loop
619 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
620
621 /// check whether RTL interface or not
622 if(!AllSettings::GetLayoutRTL())
623 aCurrPaintOffset.AdjustX(mnColWidth );
624 else aCurrPaintOffset.AdjustX( -mnColWidth );
625 ++nCurrCol;
626 if ( nCurrCol > mnCols )
627 {
628 ++nConsideredRows;
629 aCurrPaintOffset.setX( aInitialPaintOffset.X() );
630 nCurrCol = 1;
631 aCurrPaintOffset.AdjustY(mnRowHeight );
632 }
633 }
634}
635
636/** determines preview data for a given page and a given preview offset
637
638 OD 13.12.2002 #103492#
639*/
640void SwPagePreviewLayout::CalcPreviewDataForPage( const SwPageFrame& _rPage,
641 const Point& _rPreviewOffset,
642 PreviewPage* _opPreviewPage )
643{
644 // page frame
645 _opPreviewPage->pPage = &_rPage;
646 // size of page frame
647 if ( _rPage.IsEmptyPage() )
648 {
649 if ( _rPage.GetPhyPageNum() % 2 == 0 )
650 _opPreviewPage->aPageSize = _rPage.GetPrev()->getFrameArea().SSize();
651 else
652 _opPreviewPage->aPageSize = _rPage.GetNext()->getFrameArea().SSize();
653 }
654 else
655 _opPreviewPage->aPageSize = _rPage.getFrameArea().SSize();
656 // position of page in preview window
657 Point aPreviewWinOffset( _rPreviewOffset );
658 if ( _opPreviewPage->aPageSize.Width() < maMaxPageSize.Width() )
659 aPreviewWinOffset.AdjustX(( maMaxPageSize.Width() - _opPreviewPage->aPageSize.Width() ) / 2 );
660 if ( _opPreviewPage->aPageSize.Height() < maMaxPageSize.Height() )
661 aPreviewWinOffset.AdjustY(( maMaxPageSize.Height() - _opPreviewPage->aPageSize.Height() ) / 2 );
662 _opPreviewPage->aPreviewWinPos = aPreviewWinOffset;
663 // logic position of page and mapping offset for paint
664 if ( _rPage.IsEmptyPage() )
665 {
666 _opPreviewPage->aLogicPos = _opPreviewPage->aPreviewWinPos;
667 _opPreviewPage->aMapOffset = Point( 0, 0 );
668 }
669 else
670 {
671 _opPreviewPage->aLogicPos = _rPage.getFrameArea().Pos();
672 _opPreviewPage->aMapOffset = _opPreviewPage->aPreviewWinPos - _opPreviewPage->aLogicPos;
673 }
674}
675
676/** enable/disable book preview
677
678 OD 2004-03-04 #i18143#
679*/
680bool SwPagePreviewLayout::SetBookPreviewMode( const bool _bEnableBookPreview,
681 sal_uInt16& _onStartPageNum,
682 tools::Rectangle& _orDocPreviewPaintRect )
683{
684 if ( mbBookPreview != _bEnableBookPreview)
685 {
686 mbBookPreview = _bEnableBookPreview;
687 // re-initialize page preview layout
688 ReInit();
689 // re-prepare page preview layout
690 {
691 mbBookPreviewModeToggled = true;
692 Point aProposedStartPos( maPaintPreviewDocOffset );
693 // if proposed start position is below virtual preview document
694 // bottom, adjust it to the virtual preview document bottom
695 if ( aProposedStartPos.Y() > maPreviewDocRect.Bottom() )
696 {
697 aProposedStartPos.setY( maPreviewDocRect.Bottom() );
698 }
699 Prepare( 0, aProposedStartPos,
700 mrParentViewShell.GetOut()->LogicToPixel( maWinSize ),
701 _onStartPageNum, _orDocPreviewPaintRect );
702 mbBookPreviewModeToggled = false;
703 }
704
705 return true;
706 }
707
708 return false;
709}
710
711// methods to determine new data for changing the current shown part of the
712// document preview.
713
714/** calculate start position for new scale
715
716*/
717Point SwPagePreviewLayout::GetPreviewStartPosForNewScale(
718 const Fraction& _aNewScale,
719 const Fraction& _aOldScale,
720 const Size& _aNewWinSize ) const
721{
722 Point aNewPaintStartPos = maPaintedPreviewDocRect.TopLeft();
723 if ( _aNewScale < _aOldScale )
724 {
725 // increase paint width by moving start point to left.
726 if ( mnPreviewLayoutWidth < _aNewWinSize.Width() )
727 aNewPaintStartPos.setX( 0 );
728 else if ( maPaintedPreviewDocRect.GetWidth() < _aNewWinSize.Width() )
729 {
730 aNewPaintStartPos.AdjustX( -(
731 (_aNewWinSize.Width() - maPaintedPreviewDocRect.GetWidth()) / 2) );
732 if ( aNewPaintStartPos.X() < 0)
733 aNewPaintStartPos.setX( 0 );
734 }
735
736 if ( !mbDoesLayoutRowsFitIntoWindow )
737 {
738 // increase paint height by moving start point to top.
739 if ( mnPreviewLayoutHeight < _aNewWinSize.Height() )
740 {
741 aNewPaintStartPos.setY(
742 (mnPaintStartRow - 1) * mnRowHeight );
743 }
744 else if ( maPaintedPreviewDocRect.GetHeight() < _aNewWinSize.Height() )
745 {
746 aNewPaintStartPos.AdjustY( -(
747 (_aNewWinSize.Height() - maPaintedPreviewDocRect.GetHeight()) / 2) );
748 if ( aNewPaintStartPos.Y() < 0)
749 aNewPaintStartPos.setY( 0 );
750 }
751 }
752 }
753 else
754 {
755 // decrease paint width by moving start point to right
756 if ( maPaintedPreviewDocRect.GetWidth() > _aNewWinSize.Width() )
757 aNewPaintStartPos.AdjustX(
758 (maPaintedPreviewDocRect.GetWidth() - _aNewWinSize.Width()) / 2 );
759 // decrease paint height by moving start point to bottom
760 if ( maPaintedPreviewDocRect.GetHeight() > _aNewWinSize.Height() )
761 {
762 aNewPaintStartPos.AdjustY(
763 (maPaintedPreviewDocRect.GetHeight() - _aNewWinSize.Height()) / 2 );
764 // check, if new y-position is outside document preview
765 if ( aNewPaintStartPos.Y() > maPreviewDocRect.Bottom() )
766 aNewPaintStartPos.setY(
767 std::max( 0L, maPreviewDocRect.Bottom() - mnPreviewLayoutHeight ) );
768 }
769 }
770
771 return aNewPaintStartPos;
772}
773
774/** determines, if page with given page number is visible in preview
775
776 @note _nPageNum is absolute
777*/
778bool SwPagePreviewLayout::IsPageVisible( const sal_uInt16 _nPageNum ) const
779{
780 const PreviewPage* pPreviewPage = GetPreviewPageByPageNum( _nPageNum );
781 return pPreviewPage && pPreviewPage->bVisible;
782}
783
784/** calculate data to bring new selected page into view.
785
786 @note IN/OUT parameters are absolute page numbers!!!
787*/
788void SwPagePreviewLayout::CalcStartValuesForSelectedPageMove(
789 const sal_Int16 _nHoriMove,
790 const sal_Int16 _nVertMove,
791 sal_uInt16& _orNewSelectedPage,
792 sal_uInt16& _orNewStartPage,
793 Point& _orNewStartPos ) const
794{
795 // determine position of current selected page
796 sal_uInt16 nTmpRelSelPageNum = ConvertAbsoluteToRelativePageNum( mnSelectedPageNum );
797 sal_uInt16 nNewRelSelectedPageNum = nTmpRelSelPageNum;
798
799 const sal_uInt16 nCurrRow = GetRowOfPage(nTmpRelSelPageNum);
800
801 // determine new selected page number
802 {
803 if ( _nHoriMove != 0 )
804 {
805 if ( (nNewRelSelectedPageNum + _nHoriMove) < 1 )
806 nNewRelSelectedPageNum = 1;
807 else if ( (nNewRelSelectedPageNum + _nHoriMove) > mnPages )
808 nNewRelSelectedPageNum = mnPages;
809 else
810 nNewRelSelectedPageNum = nNewRelSelectedPageNum + _nHoriMove;
811 }
812 if ( _nVertMove != 0 )
813 {
814 if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) < 1 )
815 nNewRelSelectedPageNum = 1;
816 else if ( (nNewRelSelectedPageNum + (_nVertMove * mnCols)) > mnPages )
817 nNewRelSelectedPageNum = mnPages;
818 else
819 nNewRelSelectedPageNum += ( _nVertMove * mnCols );
820 }
821 }
822
823 sal_uInt16 nNewStartPage = mnPaintPhyStartPageNum;
824 Point aNewStartPos(0,0);
825
826 const sal_uInt16 nNewAbsSelectedPageNum = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
827 if ( !IsPageVisible( nNewAbsSelectedPageNum ) )
828 {
829 if ( _nHoriMove != 0 && _nVertMove != 0 )
830 {
831 OSL_FAIL( "missing implementation for moving preview selected page horizontal AND vertical")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "831" ": "), "%s", "missing implementation for moving preview selected page horizontal AND vertical"
); } } while (false)
;
832 return;
833 }
834
835 // new selected page has to be brought into view considering current
836 // visible preview.
837 const sal_uInt16 nTotalRows = GetRowOfPage( mnPages );
838 if ( (_nHoriMove > 0 || _nVertMove > 0) &&
839 mbDoesLayoutRowsFitIntoWindow &&
840 mbDoesLayoutColsFitIntoWindow &&
841 nCurrRow > nTotalRows - mnRows )
842 {
843 // new proposed start page = left-top-corner of last possible
844 // preview page.
845 nNewStartPage = (nTotalRows - mnRows) * mnCols + 1;
846 // leaving left-top-corner blank is controlled
847 // by <mbBookPreview>.
848 if ( mbBookPreview )
849 {
850 // Note: decrease new proposed start page number by one,
851 // because of blank left-top-corner
852 --nNewStartPage;
853 }
854 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewStartPage );
855 }
856 else
857 {
858 // new proposed start page = new selected page.
859 nNewStartPage = ConvertRelativeToAbsolutePageNum( nNewRelSelectedPageNum );
860 }
861 }
862
863 _orNewSelectedPage = nNewAbsSelectedPageNum;
864 _orNewStartPage = nNewStartPage;
865 _orNewStartPos = aNewStartPos;
866}
867
868namespace {
869
870/** checks, if given position is inside a shown document page */
871struct PreviewPosInsidePagePred
872{
873 const Point mnPreviewPos;
874 explicit PreviewPosInsidePagePred(const Point& rPreviewPos)
875 : mnPreviewPos( rPreviewPos )
876 {}
877 bool operator() ( const std::unique_ptr<PreviewPage> & _pPreviewPage )
878 {
879 if ( _pPreviewPage->bVisible )
880 {
881 tools::Rectangle aPreviewPageRect( _pPreviewPage->aPreviewWinPos, _pPreviewPage->aPageSize );
882 return aPreviewPageRect.IsInside( mnPreviewPos );
883 }
884 return false;
885 }
886};
887
888}
889
890bool SwPagePreviewLayout::IsPreviewPosInDocPreviewPage( const Point& rPreviewPos,
891 Point& _orDocPos,
892 bool& _obPosInEmptyPage,
893 sal_uInt16& _onPageNum ) const
894{
895 // initialize variable parameter values.
896 _orDocPos.setX( 0 );
897 _orDocPos.setY( 0 );
898 _obPosInEmptyPage = false;
899 _onPageNum = 0;
900
901 auto aFoundPreviewPageIter =
902 std::find_if( maPreviewPages.begin(), maPreviewPages.end(),
903 PreviewPosInsidePagePred( rPreviewPos ) );
904
905 if ( aFoundPreviewPageIter != maPreviewPages.end() )
906 {
907 // given preview position is inside a document page.
908 _onPageNum = (*aFoundPreviewPageIter)->pPage->GetPhyPageNum();
909 _obPosInEmptyPage = (*aFoundPreviewPageIter)->pPage->IsEmptyPage();
910 if ( !_obPosInEmptyPage )
911 {
912 // given preview position inside a normal page
913 _orDocPos = rPreviewPos -
914 (*aFoundPreviewPageIter)->aPreviewWinPos +
915 (*aFoundPreviewPageIter)->aLogicPos;
916 return true;
917 }
918 }
919
920 return false;
921}
922
923/** determine window page scroll amount */
924SwTwips SwPagePreviewLayout::GetWinPagesScrollAmount(
925 const sal_Int16 _nWinPagesToScroll ) const
926{
927 SwTwips nScrollAmount;
928 if ( mbDoesLayoutRowsFitIntoWindow )
929 {
930 nScrollAmount = (mnPreviewLayoutHeight - gnYFree) * _nWinPagesToScroll;
931 }
932 else
933 nScrollAmount = _nWinPagesToScroll * maPaintedPreviewDocRect.GetHeight();
934
935 // check, if preview layout size values are valid.
936 // If not, the checks for an adjustment of the scroll amount aren't useful.
937 if ( mbLayoutSizesValid )
938 {
939 if ( (maPaintedPreviewDocRect.Top() + nScrollAmount) <= 0 )
940 nScrollAmount = -maPaintedPreviewDocRect.Top();
941
942 // correct scroll amount
943 if ( nScrollAmount > 0 &&
944 maPaintedPreviewDocRect.Bottom() == maPreviewDocRect.Bottom()
945 )
946 {
947 nScrollAmount = 0;
948 }
949 else
950 {
951 while ( (maPaintedPreviewDocRect.Top() + nScrollAmount + gnYFree) >= maPreviewDocRect.GetHeight() )
952 {
953 nScrollAmount -= mnRowHeight;
954 }
955 }
956 }
957
958 return nScrollAmount;
959}
960
961// methods to paint page preview layout
962
963namespace
964{
965/// Similar to RenderContextGuard, but does not touch the draw view.
966class PreviewRenderContextGuard
967{
968 VclPtr<vcl::RenderContext> m_pOriginalValue;
969 SwViewShell& m_rShell;
970
971public:
972 PreviewRenderContextGuard(SwViewShell& rShell, vcl::RenderContext* pValue)
973 : m_pOriginalValue(rShell.GetOut()),
2
Calling constructor for 'VclPtr<OutputDevice>'
7
Returning from constructor for 'VclPtr<OutputDevice>'
974 m_rShell(rShell)
975 {
976 m_rShell.SetOut(pValue);
8
Calling 'SwViewShell::SetOut'
20
Returning; memory was released
977 }
978
979 ~PreviewRenderContextGuard()
980 {
981 m_rShell.SetOut(m_pOriginalValue);
28
Calling 'VclPtr::operator OutputDevice *'
982 }
983};
984}
985
986/** paint prepared preview
987
988*/
989bool SwPagePreviewLayout::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rOutRect) const
990{
991 PreviewRenderContextGuard aGuard(mrParentViewShell, &rRenderContext);
1
Calling constructor for 'PreviewRenderContextGuard'
21
Returning from constructor for 'PreviewRenderContextGuard'
992 // check environment and parameters
993 {
994 if (!mrParentViewShell.GetWin() && !mrParentViewShell.GetOut()->GetConnectMetaFile())
22
Assuming the condition is false
995 {
996 return false;
997 }
998
999 OSL_ENSURE(mbPaintInfoValid, "invalid preview settings - no paint of preview")do { if (true && (!(mbPaintInfoValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "999" ": "), "%s", "invalid preview settings - no paint of preview"
); } } while (false)
;
23
Assuming field 'mbPaintInfoValid' is false
24
Taking true branch
25
Loop condition is false. Exiting loop
1000 if (!mbPaintInfoValid
25.1
Field 'mbPaintInfoValid' is false
25.1
Field 'mbPaintInfoValid' is false
25.1
Field 'mbPaintInfoValid' is false
25.1
Field 'mbPaintInfoValid' is false
25.1
Field 'mbPaintInfoValid' is false
)
26
Taking true branch
1001 return false;
27
Calling '~PreviewRenderContextGuard'
1002 }
1003
1004 // OD 17.11.2003 #i22014# - no paint, if <superfluous> flag is set at layout
1005 if (mrLayoutRootFrame.IsSuperfluous())
1006 {
1007 return true;
1008 }
1009
1010 // environment and parameter ok
1011
1012 if (mbInPaint)
1013 {
1014 return false;
1015 }
1016 mbInPaint = true;
1017
1018 OutputDevice* pOutputDev = &rRenderContext;
1019
1020 // prepare paint
1021 if ( !maPreviewPages.empty() )
1022 {
1023 mrParentViewShell.Imp()->m_bFirstPageInvalid = false;
1024 mrParentViewShell.Imp()->m_pFirstVisiblePage =
1025 const_cast<SwPageFrame*>(maPreviewPages[0]->pPage);
1026 }
1027
1028 // paint preview background
1029 {
1030 SwRegionRects aPreviewBackgrdRegion(rOutRect);
1031 // calculate preview background rectangles
1032 for ( auto & rpPreviewPage : maPreviewPages )
1033 {
1034 if ( rpPreviewPage->bVisible )
1035 {
1036 aPreviewBackgrdRegion -=
1037 SwRect( rpPreviewPage->aPreviewWinPos, rpPreviewPage->aPageSize );
1038 }
1039 }
1040 // paint preview background rectangles
1041 mrParentViewShell.PaintDesktop_(aPreviewBackgrdRegion);
1042 }
1043
1044 // prepare data for paint of pages
1045 const tools::Rectangle aPxOutRect( pOutputDev->LogicToPixel(rOutRect) );
1046
1047 MapMode aMapMode( pOutputDev->GetMapMode() );
1048 MapMode aSavedMapMode = aMapMode;
1049
1050 const vcl::Font& rEmptyPgFont = SwPageFrame::GetEmptyPageFont();
1051
1052 for ( auto & rpPreviewPage : maPreviewPages )
1053 {
1054 if ( !rpPreviewPage->bVisible )
1055 continue;
1056
1057 tools::Rectangle aPageRect( rpPreviewPage->aLogicPos, rpPreviewPage->aPageSize );
1058 aMapMode.SetOrigin( rpPreviewPage->aMapOffset );
1059 pOutputDev->SetMapMode( aMapMode );
1060 tools::Rectangle aPxPaintRect = pOutputDev->LogicToPixel( aPageRect );
1061 if ( aPxOutRect.IsOver( aPxPaintRect) )
1062 {
1063 const SwPageFrame* pPage = rpPreviewPage->pPage;
1064
1065 if (pPage->IsEmptyPage())
1066 {
1067 const Color aRetouche( mrParentViewShell.Imp()->GetRetoucheColor() );
1068 if( pOutputDev->GetFillColor() != aRetouche )
1069 pOutputDev->SetFillColor( aRetouche );
1070 pOutputDev->SetLineColor(); // no line color
1071 // use aligned page rectangle
1072 {
1073 SwRect aTmpPageRect( aPageRect );
1074 ::SwAlignRect( aTmpPageRect, &mrParentViewShell, &rRenderContext );
1075 aPageRect = aTmpPageRect.SVRect();
1076 }
1077 pOutputDev->DrawRect( aPageRect );
1078
1079 // paint empty page text
1080 vcl::Font aOldFont( pOutputDev->GetFont() );
1081 pOutputDev->SetFont( rEmptyPgFont );
1082 pOutputDev->DrawText( aPageRect, SwResId( STR_EMPTYPAGEreinterpret_cast<char const *>("STR_EMPTYPAGE" "\004" u8"blank page"
)
),
1083 DrawTextFlags::VCenter |
1084 DrawTextFlags::Center |
1085 DrawTextFlags::Clip );
1086 pOutputDev->SetFont( aOldFont );
1087 // paint shadow and border for empty page
1088 // use new method to paint page border and shadow
1089 SwPageFrame::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, false, true );
1090 }
1091 else
1092 {
1093 const bool bIsLeftShadowed = pPage->IsLeftShadowNeeded();
1094 const bool bIsRightShadowed = pPage->IsRightShadowNeeded();
1095
1096 mrParentViewShell.maVisArea = aPageRect;
1097 aPxPaintRect.Intersection( aPxOutRect );
1098 tools::Rectangle aPaintRect = pOutputDev->PixelToLogic( aPxPaintRect );
1099 mrParentViewShell.Paint(rRenderContext, aPaintRect);
1100
1101 // --> OD 2007-08-15 #i80691#
1102 // paint page border and shadow
1103 {
1104 SwRect aPageBorderRect;
1105 SwPageFrame::GetBorderAndShadowBoundRect( SwRect( aPageRect ), &mrParentViewShell, &rRenderContext, aPageBorderRect,
1106 bIsLeftShadowed, bIsRightShadowed, true );
1107 const vcl::Region aDLRegion(aPageBorderRect.SVRect());
1108 mrParentViewShell.DLPrePaint2(aDLRegion);
1109 SwPageFrame::PaintBorderAndShadow( aPageRect, &mrParentViewShell, true, false, true );
1110 mrParentViewShell.DLPostPaint2(true);
1111 }
1112 // <--
1113 }
1114 // OD 07.11.2003 #i22014# - stop painting, because new print
1115 // preview layout is created during paint.
1116 if ( mbNewLayoutDuringPaint )
1117 {
1118 break;
1119 }
1120
1121 if (pPage->GetPhyPageNum() == mnSelectedPageNum)
1122 {
1123 PaintSelectMarkAtPage(rRenderContext, rpPreviewPage.get());
1124 }
1125 }
1126 }
1127
1128 // OD 17.11.2003 #i22014# - no update of accessible preview, if a new
1129 // print preview layout is created during paint.
1130 if ( !mbNewLayoutDuringPaint )
1131 {
1132 // update at accessibility interface
1133 mrParentViewShell.Imp()->UpdateAccessiblePreview(
1134 maPreviewPages,
1135 aMapMode.GetScaleX(),
1136 mrLayoutRootFrame.GetPageByPageNum( mnSelectedPageNum ),
1137 maWinSize );
1138 }
1139
1140 pOutputDev->SetMapMode( aSavedMapMode );
1141 mrParentViewShell.maVisArea.Clear();
1142
1143 // OD 07.11.2003 #i22014#
1144 mbInPaint = false;
1145 mbNewLayoutDuringPaint = false;
1146
1147 return true;
1148}
1149
1150/** repaint pages on page preview
1151
1152 OD 18.12.2002 #103492#
1153*/
1154void SwPagePreviewLayout::Repaint( const tools::Rectangle& rInvalidCoreRect ) const
1155{
1156 // check environment and parameters
1157 {
1158 if ( !mrParentViewShell.GetWin() &&
1159 !mrParentViewShell.GetOut()->GetConnectMetaFile() )
1160 return;
1161
1162 OSL_ENSURE( mbPaintInfoValid,do { if (true && (!(mbPaintInfoValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "1163" ": "), "%s", "invalid preview settings - no paint of preview"
); } } while (false)
1163 "invalid preview settings - no paint of preview" )do { if (true && (!(mbPaintInfoValid))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "1163" ": "), "%s", "invalid preview settings - no paint of preview"
); } } while (false)
;
1164 if ( !mbPaintInfoValid )
1165 return;
1166 }
1167
1168 // environment and parameter ok
1169
1170 // prepare paint
1171 if ( !maPreviewPages.empty() )
1172 {
1173 mrParentViewShell.Imp()->m_bFirstPageInvalid = false;
1174 mrParentViewShell.Imp()->m_pFirstVisiblePage =
1175 const_cast<SwPageFrame*>(maPreviewPages[0]->pPage);
1176 }
1177
1178 // invalidate visible pages, which overlap the invalid core rectangle
1179 for ( auto & rpPreviewPage : maPreviewPages )
1180 {
1181 if ( !rpPreviewPage->bVisible )
1182 continue;
1183
1184 tools::Rectangle aPageRect( rpPreviewPage->aLogicPos, rpPreviewPage->aPageSize );
1185 if ( rInvalidCoreRect.IsOver( aPageRect ) )
1186 {
1187 aPageRect.Intersection(rInvalidCoreRect);
1188 tools::Rectangle aInvalidPreviewRect = aPageRect;
1189 aInvalidPreviewRect.SetPos( aInvalidPreviewRect.TopLeft() -
1190 rpPreviewPage->aLogicPos +
1191 rpPreviewPage->aPreviewWinPos );
1192 mrParentViewShell.GetWin()->Invalidate( aInvalidPreviewRect );
1193 }
1194 }
1195}
1196
1197/** paint selection mark at page
1198
1199 OD 17.12.2002 #103492#
1200*/
1201void SwPagePreviewLayout::PaintSelectMarkAtPage(vcl::RenderContext& rRenderContext,
1202 const PreviewPage* _aSelectedPreviewPage ) const
1203{
1204 OutputDevice* pOutputDev = &rRenderContext;
1205 MapMode aMapMode( pOutputDev->GetMapMode() );
1206 // save mapping mode of output device
1207 MapMode aSavedMapMode = aMapMode;
1208 // save fill and line color of output device
1209 Color aFill( pOutputDev->GetFillColor() );
1210 Color aLine( pOutputDev->GetLineColor() );
1211
1212 // determine selection mark color
1213 Color aSelPgLineColor(117, 114, 106);
1214 const StyleSettings& rSettings =
1215 mrParentViewShell.GetWin()->GetSettings().GetStyleSettings();
1216 if ( rSettings.GetHighContrastMode() )
1217 aSelPgLineColor = rSettings.GetHighlightTextColor();
1218
1219 // set needed mapping mode at output device
1220 aMapMode.SetOrigin( _aSelectedPreviewPage->aMapOffset );
1221 pOutputDev->SetMapMode( aMapMode );
1222
1223 // calculate page rectangle in pixel coordinates
1224 SwRect aPageRect( _aSelectedPreviewPage->aLogicPos,
1225 _aSelectedPreviewPage->aPageSize );
1226 // OD 19.02.2003 #107369# - use aligned page rectangle, as it is used for
1227 // page border and shadow paint - see <SwPageFrame::PaintBorderAndShadow(..)>
1228 ::SwAlignRect( aPageRect, &mrParentViewShell, pOutputDev );
1229 tools::Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1230
1231 // draw two rectangle
1232 // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1233 tools::Rectangle aRect( aPxPageRect.Left(), aPxPageRect.Top(),
1234 aPxPageRect.Right(), aPxPageRect.Bottom() );
1235 aRect = pOutputDev->PixelToLogic( aRect );
1236 pOutputDev->SetFillColor(); // OD 20.02.2003 #107369# - no fill color
1237 pOutputDev->SetLineColor( aSelPgLineColor );
1238 pOutputDev->DrawRect( aRect );
1239 // OD 19.02.2003 #107369# - adjust position of select mark rectangle
1240 aRect = tools::Rectangle( aPxPageRect.Left()+1, aPxPageRect.Top()+1,
1241 aPxPageRect.Right()-1, aPxPageRect.Bottom()-1 );
1242 aRect = pOutputDev->PixelToLogic( aRect );
1243 pOutputDev->DrawRect( aRect );
1244
1245 // reset fill and line color of output device
1246 pOutputDev->SetFillColor( aFill );
1247 pOutputDev->SetLineColor( aLine );
1248
1249 // reset mapping mode of output device
1250 pOutputDev->SetMapMode( aSavedMapMode );
1251}
1252
1253/** paint to mark new selected page
1254
1255 OD 17.12.2002 #103492#
1256 Perform paint for current selected page in order to unmark it.
1257 Set new selected page and perform paint to mark this page.
1258
1259 @note _nSelectedPage, mnSelectedPage are absolute
1260*/
1261void SwPagePreviewLayout::MarkNewSelectedPage( const sal_uInt16 _nSelectedPage )
1262{
1263 const sal_uInt16 nOldSelectedPageNum = mnSelectedPageNum;
1264 mnSelectedPageNum = _nSelectedPage;
1265
1266 // re-paint for current selected page in order to unmark it.
1267 const PreviewPage* pOldSelectedPreviewPage = GetPreviewPageByPageNum( nOldSelectedPageNum );
1268 OutputDevice* pOutputDev = mrParentViewShell.GetOut();
1269 if ( pOldSelectedPreviewPage && pOldSelectedPreviewPage->bVisible )
1270 {
1271 // OD 20.02.2003 #107369# - invalidate only areas of selection mark.
1272 SwRect aPageRect( pOldSelectedPreviewPage->aPreviewWinPos,
1273 pOldSelectedPreviewPage->aPageSize );
1274 ::SwAlignRect( aPageRect, &mrParentViewShell, pOutputDev );
1275 tools::Rectangle aPxPageRect = pOutputDev->LogicToPixel( aPageRect.SVRect() );
1276 // invalidate top mark line
1277 tools::Rectangle aInvalPxRect( aPxPageRect.Left(), aPxPageRect.Top(),
1278 aPxPageRect.Right(), aPxPageRect.Top()+1 );
1279 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1280 // invalidate right mark line
1281 aInvalPxRect = tools::Rectangle( aPxPageRect.Right()-1, aPxPageRect.Top(),
1282 aPxPageRect.Right(), aPxPageRect.Bottom() );
1283 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1284 // invalidate bottom mark line
1285 aInvalPxRect = tools::Rectangle( aPxPageRect.Left(), aPxPageRect.Bottom()-1,
1286 aPxPageRect.Right(), aPxPageRect.Bottom() );
1287 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1288 // invalidate left mark line
1289 aInvalPxRect = tools::Rectangle( aPxPageRect.Left(), aPxPageRect.Top(),
1290 aPxPageRect.Left()+1, aPxPageRect.Bottom() );
1291 mrParentViewShell.GetWin()->Invalidate( pOutputDev->PixelToLogic( aInvalPxRect ) );
1292 }
1293
1294 // re-paint for new selected page in order to mark it.
1295 const PreviewPage* pNewSelectedPreviewPage = GetPreviewPageByPageNum( _nSelectedPage );
1296 if ( pNewSelectedPreviewPage && pNewSelectedPreviewPage->bVisible )
1297 {
1298 const PreviewPage* pSelectedPreviewPage = GetPreviewPageByPageNum(mnSelectedPageNum);
1299 SwRect aPageRect(pSelectedPreviewPage->aPreviewWinPos, pSelectedPreviewPage->aPageSize);
1300 ::SwAlignRect(aPageRect, &mrParentViewShell, pOutputDev);
1301 mrParentViewShell.GetWin()->Invalidate(aPageRect.SVRect());
1302 }
1303}
1304
1305// helper methods
1306
1307namespace {
1308
1309/** get preview page by physical page number
1310
1311 OD 17.12.2002 #103492#
1312*/
1313struct EqualsPageNumPred
1314{
1315 const sal_uInt16 mnPageNum;
1316 explicit EqualsPageNumPred(const sal_uInt16 _nPageNum)
1317 : mnPageNum( _nPageNum )
1318 {}
1319 bool operator() ( const std::unique_ptr<PreviewPage> & _pPreviewPage )
1320 {
1321 return _pPreviewPage->pPage->GetPhyPageNum() == mnPageNum;
1322 }
1323};
1324
1325}
1326
1327const PreviewPage* SwPagePreviewLayout::GetPreviewPageByPageNum( const sal_uInt16 _nPageNum ) const
1328{
1329 auto aFoundPreviewPageIter =
1330 std::find_if( maPreviewPages.begin(), maPreviewPages.end(),
1331 EqualsPageNumPred( _nPageNum ) );
1332
1333 if ( aFoundPreviewPageIter == maPreviewPages.end() )
1334 return nullptr;
1335
1336 return aFoundPreviewPageIter->get();
1337}
1338
1339/** determine row the page with the given number is in
1340
1341 OD 17.01.2003 #103492#
1342
1343 @note _nPageNum is relative
1344*/
1345sal_uInt16 SwPagePreviewLayout::GetRowOfPage( sal_uInt16 _nPageNum ) const
1346{
1347 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1348 // by <mbBookPreview>.
1349 if ( mbBookPreview )
1350 {
1351 // Note: increase given physical page number by one, because left-top-corner
1352 // in the preview layout is left blank.
1353 ++_nPageNum;
1354 }
1355
1356 return _nPageNum / mnCols + ((_nPageNum % mnCols)>0 ? 1 : 0);
1357}
1358
1359/** determine column the page with the given number is in
1360
1361 OD 17.01.2003 #103492#
1362
1363 @note _nPageNum is relative
1364*/
1365sal_uInt16 SwPagePreviewLayout::GetColOfPage( sal_uInt16 _nPageNum ) const
1366{
1367 // OD 19.02.2003 #107369# - leaving left-top-corner blank is controlled
1368 // by <mbBookPreview>.
1369 if ( mbBookPreview )
1370 {
1371 // Note: increase given physical page number by one, because left-top-corner
1372 // in the preview layout is left blank.
1373 ++_nPageNum;
1374 }
1375
1376 const sal_uInt16 nCol = _nPageNum % mnCols;
1377 return nCol ? nCol : mnCols;
1378}
1379
1380Size SwPagePreviewLayout::GetPreviewDocSize() const
1381{
1382 OSL_ENSURE( PreviewLayoutValid(), "PagePreviewLayout not valid" )do { if (true && (!(PreviewLayoutValid()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/pagepreviewlayout.cxx"
":" "1382" ": "), "%s", "PagePreviewLayout not valid"); } } while
(false)
;
1383 return maPreviewDocRect.GetSize();
1384}
1385
1386/** get size of a preview page by its physical page number
1387
1388 OD 15.01.2003 #103492#
1389*/
1390Size SwPagePreviewLayout::GetPreviewPageSizeByPageNum( sal_uInt16 _nPageNum ) const
1391{
1392 const PreviewPage* pPreviewPage = GetPreviewPageByPageNum( _nPageNum );
1393 if ( pPreviewPage )
1394 {
1395 return pPreviewPage->aPageSize;
1396 }
1397 return Size( 0, 0 );
1398}
1399
1400/** get virtual page number by its physical page number
1401
1402 OD 21.03.2003 #108282#
1403*/
1404sal_uInt16 SwPagePreviewLayout::GetVirtPageNumByPageNum( sal_uInt16 _nPageNum ) const
1405{
1406 const PreviewPage* pPreviewPage = GetPreviewPageByPageNum( _nPageNum );
1407 if ( pPreviewPage )
1408 {
1409 return pPreviewPage->pPage->GetVirtPageNum();
1410 }
1411 return 0;
1412}
1413
1414/** Convert absolute to relative page numbers (see PrintEmptyPages) */
1415sal_uInt16 SwPagePreviewLayout::ConvertAbsoluteToRelativePageNum( sal_uInt16 _nAbsPageNum ) const
1416{
1417 if ( mbBookPreview || mbPrintEmptyPages || !_nAbsPageNum )
1418 {
1419 return _nAbsPageNum;
1420 }
1421
1422 const SwPageFrame* pTmpPage = static_cast<const SwPageFrame*>(mrLayoutRootFrame.Lower());
1423
1424 sal_uInt16 nRet = 1;
1425
1426 while ( pTmpPage && pTmpPage->GetPhyPageNum() != _nAbsPageNum )
1427 {
1428 if ( !pTmpPage->IsEmptyPage() )
1429 ++nRet;
1430
1431 pTmpPage = static_cast<const SwPageFrame*>( pTmpPage->GetNext() );
1432 }
1433
1434 return nRet;
1435}
1436
1437/** Convert relative to absolute page numbers (see PrintEmptyPages) */
1438sal_uInt16 SwPagePreviewLayout::ConvertRelativeToAbsolutePageNum( sal_uInt16 _nRelPageNum ) const
1439{
1440 if ( mbBookPreview || mbPrintEmptyPages || !_nRelPageNum )
1441 {
1442 return _nRelPageNum;
1443 }
1444
1445 const SwPageFrame* pTmpPage = static_cast<const SwPageFrame*>(mrLayoutRootFrame.Lower());
1446 const SwPageFrame* pRet = nullptr;
1447
1448 sal_uInt16 i = 0;
1449 while( pTmpPage && i != _nRelPageNum )
1450 {
1451 if ( !pTmpPage->IsEmptyPage() )
1452 ++i;
1453
1454 pRet = pTmpPage;
1455 pTmpPage = static_cast<const SwPageFrame*>( pTmpPage->GetNext() );
1456 }
1457
1458 return pRet->GetPhyPageNum();
1459}
1460
1461/* 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)
3
Calling constructor for 'Reference<OutputDevice>'
6
Returning from constructor for 'Reference<OutputDevice>'
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);
10
Calling 'Reference::set'
18
Returning; memory was released
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
29
Calling 'Reference::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)
4
Assuming field 'm_pBody' is non-null
5
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)
113 m_pBody->release();
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody
10.1
'pBody' is non-null
10.1
'pBody' is non-null
10.1
'pBody' is non-null
10.1
'pBody' is non-null
10.1
'pBody' is non-null
)
11
Taking true branch
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld
11.1
'pOld' is non-null
11.1
'pOld' is non-null
11.1
'pOld' is non-null
11.1
'pOld' is non-null
11.1
'pOld' is non-null
)
12
Taking true branch
127 pOld->release();
13
Calling 'VclReferenceBase::release'
17
Returning; memory was released
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;
30
Use of memory after it is freed
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/sw/inc/viewsh.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_SW_INC_VIEWSH_HXX
20#define INCLUDED_SW_INC_VIEWSH_HXX
21
22#include "swdllapi.h"
23#include "swtypes.hxx"
24#include "ring.hxx"
25#include "swrect.hxx"
26#include <memory>
27#include <stack>
28#include <vcl/mapmod.hxx>
29#include <vcl/vclptr.hxx>
30#include <vcl/lazydelete.hxx>
31#include <vcl/window.hxx>
32
33namespace com::sun::star::accessibility { class XAccessible; }
34class SwDoc;
35class IDocumentSettingAccess;
36class IDocumentDeviceAccess;
37class IDocumentMarkAccess;
38class IDocumentDrawModelAccess;
39class IDocumentRedlineAccess;
40class IDocumentLayoutAccess;
41class IDocumentContentOperations;
42class IDocumentStylePoolAccess;
43class IDocumentStatistics;
44class IDocumentUndoRedo;
45class IDocumentListItems;
46class IDocumentOutlineNodes;
47class SfxPrinter;
48class SwRootFrame;
49class SwNodes;
50class SdrView;
51class SfxItemPool;
52class SfxViewShell;
53class SwViewOption;
54class SwViewShellImp;
55class SwPrintData;
56struct ShellResource;
57class SwRegionRects;
58class SvtAccessibilityOptions;
59class SwPagePreviewLayout;
60class SwTextFrame;
61
62struct SwAccessibilityOptions;
63namespace vcl { class Region; }
64class SwPostItMgr;
65class SdrPaintWindow;
66class SwAccessibleMap;
67enum class Orientation;
68
69namespace vcl
70{
71 typedef OutputDevice RenderContext;
72}
73
74// Define for flags needed in ctor or layers below.
75// Currently the Preview flag is needed for DrawPage.
76#define VSHELLFLAG_ISPREVIEW(long(0x1)) (long(0x1))
77#define VSHELLFLAG_SHARELAYOUT(long(0x2)) (long(0x2))
78typedef std::shared_ptr<SwRootFrame> SwRootFramePtr;
79
80typedef struct _xmlTextWriter* xmlTextWriterPtr;
81
82class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwViewShell : public sw::Ring<SwViewShell>
83{
84 friend void SetOutDev( SwViewShell *pSh, OutputDevice *pOut );
85 friend void SetOutDevAndWin( SwViewShell *pSh, OutputDevice *pOut,
86 vcl::Window *pWin, sal_uInt16 nZoom );
87
88 friend class SwViewShellImp;
89 friend class SwLayIdle;
90
91 // For setting visible area for page preview paint.
92 friend class SwPagePreviewLayout;
93
94 // Set SwVisArea in order to enable clean formatting before printing.
95 friend void SetSwVisArea( SwViewShell *pSh, const SwRect & );
96
97 std::unique_ptr<BitmapEx> m_xReplaceBmp; ///< replaced display of still loaded images
98 std::unique_ptr<BitmapEx> m_xErrorBmp; ///< error display of missed images
99
100 static bool mbLstAct; // true if EndAction of last Shell
101 // i.e. if the EndActions of the other
102 // Shells on the document are through.
103
104 Point maPrtOffset; // Offset for Printer,
105 // non-printable margin.
106 Size maBrowseBorder; // Border for frame documents.
107 SwRect maInvalidRect;
108
109 SfxViewShell *mpSfxViewShell;
110 std::unique_ptr<SwViewShellImp>
111 mpImp; // Core-internals of SwViewShell.
112 // The pointer is never 0.
113
114 VclPtr<vcl::Window> mpWin; ///< = 0 during printing or pdf export
115 VclPtr<OutputDevice> mpOut; ///< Window, Printer, VirtDev, ...
116
117 std::unique_ptr<SwViewOption> mpOpt;
118 std::unique_ptr<SwAccessibilityOptions> mpAccOptions;
119
120 bool mbDocSizeChgd :1; // For DocChgNotify(): Announce new DocSize
121 // at EndAction to DocMDI.
122 bool mbPaintWorks :1; // Normal Painting if true,
123 // remember Paint if false.
124 bool mbPaintInProgress :1; // Block any double paint.
125 bool mbViewLocked :1; // Lock visible range;
126 // in this case MakeVisible is ineffectual.
127 bool mbInEndAction :1; // Avoid problems, cf. viewsh.cxx.
128 bool mbPreview :1; // If true it is a Preview-SwViewShell.
129 bool mbFrameView :1; // If true it is a (HTML-)Frame.
130 bool mbEnableSmooth :1; // Disable SmoothScroll, e.g. for drag
131 // of scrollbars.
132 bool mbEndActionByVirDev:1; // Paints from EndAction always via virtual device
133 // (e.g. when browsing).
134 bool mbShowHeaderSeparator:1; ///< Flag to say that we are showing the header control
135 bool mbShowFooterSeparator:1; ///< Flag to say that we are showing the footer control
136 bool mbHeaderFooterEdit:1; ///< Flag to say that we are editing header or footer (according to the bShow(Header|Footer)Separator above)
137
138 // boolean, indicating that class in constructor.
139 bool mbInConstructor:1;
140
141 SdrPaintWindow* mpTargetPaintWindow;
142 VclPtr<OutputDevice> mpBufferedOut;
143
144 SwRootFramePtr mpLayout;
145
146 // Initialization; called by the diverse constructors.
147 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void Init( const SwViewOption *pNewOpt );
148
149 inline void ResetInvalidRect();
150
151
152
153 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PaintDesktop(vcl::RenderContext& rRenderContext, const SwRect&); // Collect values for painting of desktop
154 // and calling.
155 // PaintDesktop split. This pars is also used by PreviewPage.
156 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PaintDesktop_(const SwRegionRects &rRegion);
157
158 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool CheckInvalidForPaint( const SwRect & ); // Direct Paint or rather
159 // trigger an action.
160
161 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PrepareForPrint( const SwPrintData &rOptions, bool bIsPDFExport = false );
162
163 SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplApplyViewOptions( const SwViewOption &rOpt );
164
165protected:
166 static ShellResource* mpShellRes; ///< Resources for the Shell.
167 static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > mpCareDialog; ///< Avoid this window.
168
169 SwRect maVisArea; ///< The modern version of VisArea.
170 tools::Rectangle maLOKVisibleArea;///< The visible area in the LibreOfficeKit client.
171 rtl::Reference<SwDoc> mxDoc; ///< The document; never 0.
172
173 sal_uInt16 mnStartAction; ///< != 0 if at least one Action is active.
174 sal_uInt16 mnLockPaint; ///< != 0 if Paint is locked.
175 bool mbSelectAll; ///< Special select all mode: whole document selected, even if doc starts with table.
176
177 /// The virtual device we paint to will end up on the screen.
178 bool mbOutputToWindow;
179
180public:
181
182 SwViewShellImp *Imp() { return mpImp.get(); }
183 const SwViewShellImp *Imp() const { return mpImp.get(); }
184
185 const SwNodes& GetNodes() const;
186
187 // After change of printer; by Doc.
188 void InitPrt( OutputDevice *pOutDev );
189
190 // Bracketing of actions belonging together.
191 inline void StartAction();
192 void ImplStartAction();
193 inline void EndAction( const bool bIdleEnd = false );
194 void ImplEndAction( const bool bIdleEnd );
195 sal_uInt16 ActionCount() const { return mnStartAction; }
196 bool ActionPend() const { return mnStartAction != 0; }
197 bool IsInEndAction() const { return mbInEndAction; }
198
199 void SetEndActionByVirDev( bool b ) { mbEndActionByVirDev = b; }
200 bool IsEndActionByVirDev() const { return mbEndActionByVirDev; }
201
202 // The ActionCount for all Shells is temporarily set to zero and then
203 // restored at the RootFrame via UNO.
204 void SetRestoreActions(sal_uInt16 nSet);
205 sal_uInt16 GetRestoreActions() const;
206
207 bool HasInvalidRect() const { return maInvalidRect.HasArea(); }
208 void ChgHyphenation() { Reformat(); }
209 void ChgNumberDigits();
210
211 bool AddPaintRect( const SwRect &rRect );
212
213 void InvalidateWindows( const SwRect &rRect );
214
215 /// Invalidates complete Layout (ApplyViewOption).
216 void Reformat();
217
218 // #i72754# set of Pre/PostPaints with lock counter and initial target OutDev
219protected:
220 std::stack<vcl::Region> mPrePostPaintRegions; // acts also as a lock counter (empty == not locked)
221 VclPtr<OutputDevice> mpPrePostOutDev;
222 MapMode maPrePostMapMode;
223public:
224 void PrePaint();
225 void DLPrePaint2(const vcl::Region& rRegion);
226 void DLPostPaint2(bool bPaintFormLayer);
227 const MapMode& getPrePostMapMode() const { return maPrePostMapMode; }
228
229 virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect);
230
231 /** Paint tile.
232
233 Sets the pOut so that the rRect is always painted over the entire
234 pOut, ie. starts in 0,0 and ends in width/height.
235 */
236 void PaintTile(VirtualDevice &rDevice, int contextWidth, int contextHeight, int tilePosX, int tilePosY, long tileWidth, long tileHeight);
237
238 bool IsPaintInProgress() const { return mbPaintInProgress; }
239 bool IsDrawingLayerPaintInProgress() const { return !mPrePostPaintRegions.empty(); }
240
241 // Notification that visible area has been changed.
242 // VisArea is reset, after that scrolling takes place.
243 // The passed rect is situated on pixel borders
244 // in order to avoid pixel errors when scrolling.
245 virtual void VisPortChgd( const SwRect & );
246 bool SmoothScroll( long lXDiff, long lYDiff, const tools::Rectangle* );//Browser
247 void EnableSmooth( bool b ) { mbEnableSmooth = b; }
248
249 const SwRect& VisArea() const;
250
251 /// The visible area in the client (set by setClientVisibleArea).
252 const tools::Rectangle & getLOKVisibleArea() const { return maLOKVisibleArea; }
253 void setLOKVisibleArea(const tools::Rectangle& rArea) { maLOKVisibleArea = rArea; }
254
255 // If necessary scroll until passed Rect is situated in visible sector.
256 void MakeVisible( const SwRect & );
257
258 // At nearest occasion pass new document size to UI.
259 void SizeChgNotify();
260 void UISizeNotify(); // Passing of current size.
261
262 Point GetPagePos( sal_uInt16 nPageNum ) const;
263
264 sal_uInt16 GetNumPages() const; // Ask count of current pages from layout.
265 bool IsDummyPage( sal_uInt16 nPageNum ) const; // An empty page?
266
267 // Invalidate first visible page for all Shells in ring.
268 void SetFirstVisPageInvalid();
269
270 SwRootFrame *GetLayout() const;
271 bool IsNewLayout() const; // Has Layout been loaded or created?
272
273 Size GetDocSize() const; // Get document size.
274
275 virtual void CalcLayout(); // Force complete formatting of layout.
276
277 sal_uInt16 GetPageCount() const;
278
279 Size GetPageSize( sal_uInt16 nPageNum, bool bSkipEmptyPages ) const;
280
281 SwDoc *GetDoc() const { return mxDoc.get(); } //Never 0.
282
283 /** Provides access to the document setting interface
284 */
285 const IDocumentSettingAccess& getIDocumentSettingAccess() const;
286 IDocumentSettingAccess& getIDocumentSettingAccess();
287
288 /** Provides access to the document device interface
289 */
290 const IDocumentDeviceAccess& getIDocumentDeviceAccess() const;
291 IDocumentDeviceAccess& getIDocumentDeviceAccess();
292
293 /** Provides access to the document bookmark interface
294 */
295 const IDocumentMarkAccess* getIDocumentMarkAccess() const;
296 IDocumentMarkAccess* getIDocumentMarkAccess();
297
298 /** Provides access to the document draw model interface
299 */
300 const IDocumentDrawModelAccess& getIDocumentDrawModelAccess() const;
301 IDocumentDrawModelAccess& getIDocumentDrawModelAccess();
302
303 /** Provides access to the document redline interface
304 */
305 const IDocumentRedlineAccess& getIDocumentRedlineAccess() const;
306 IDocumentRedlineAccess& getIDocumentRedlineAccess();
307
308 /** Provides access to the document layout interface
309 */
310 const IDocumentLayoutAccess& getIDocumentLayoutAccess() const;
311 IDocumentLayoutAccess& getIDocumentLayoutAccess();
312
313 /** Provides access to the content operations interface
314 */
315 IDocumentContentOperations& getIDocumentContentOperations();
316
317 /** Provides access to the document style pool interface
318 */
319 IDocumentStylePoolAccess& getIDocumentStylePoolAccess();
320
321 /** Provides access to the document statistics interface
322 */
323 const IDocumentStatistics& getIDocumentStatistics() const;
324
325 /** Provides access to the document undo/redo interface
326 */
327 IDocumentUndoRedo const& GetIDocumentUndoRedo() const;
328 IDocumentUndoRedo & GetIDocumentUndoRedo();
329
330 const IDocumentListItems* getIDocumentListItemsAccess() const;
331 const IDocumentOutlineNodes* getIDocumentOutlineNodesAccess() const;
332
333 // 1. GetRefDev: Either the printer or the virtual device from the doc
334 // 2. GetWin: Available if we not printing
335 // 3. GetOut: Printer, Window or Virtual device
336 vcl::RenderContext& GetRefDev() const;
337 vcl::Window* GetWin() const { return mpWin; }
338 vcl::RenderContext* GetOut() const { return mpOut; }
339
340 void SetWin(vcl::Window* win) { mpWin = win; }
341 void SetOut(vcl::RenderContext* pOut) { mpOut = pOut; }
9
Calling 'VclPtr::operator='
19
Returning; memory was released
342 static bool IsLstEndAction() { return SwViewShell::mbLstAct; }
343
344 // Change of all page descriptors.
345 void ChgAllPageOrientation( Orientation eOri );
346 void ChgAllPageSize( Size const &rSz );
347
348 // Printing of one page.
349 // bIsPDFExport == true is: do PDF Export (no printing!)
350 bool PrintOrPDFExport( OutputDevice *pOutDev,
351 SwPrintData const& rPrintData,
352 sal_Int32 nRenderer, /* offset in vector of pages to print */
353 bool bIsPDFExport );
354
355 // Printing of one brochure page.
356 void PrintProspect( OutputDevice *pOutDev, const SwPrintData &rPrintData,
357 sal_Int32 nRenderer /* offset in vector of page pairs for prospect printing */ );
358
359 // Printing for OLE 2.0.
360 static void PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintData& rOptions,
361 vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect );
362
363 // Fill temporary doc with selected text for Print or PDF export.
364 void FillPrtDoc( SwDoc& rPrtDoc, const SfxPrinter* pPrt );
365
366 // Called internally for Shell. Formats pages.
367 void CalcPagesForPrint( sal_uInt16 nMax );
368
369 // All about fields.
370 void UpdateFields(bool bCloseDB = false);
371 bool IsAnyFieldInDoc() const;
372 // Update all charts, for that exists any table.
373 void UpdateAllCharts();
374 bool HasCharts() const;
375
376 // DOCUMENT COMPATIBILITY FLAGS START
377
378 // Add or maximize paragraph spacing?
379 void SetParaSpaceMax( bool bNew );
380
381 // Add or maximize paragraph spacing?
382 void SetParaSpaceMaxAtPages( bool bNew );
383
384 // Compatible behaviour of tabs.
385 void SetTabCompat( bool bNew );
386
387 // Font metric attribute "External Leading" should be considered.
388 void SetAddExtLeading( bool bNew );
389
390 // Formatting by virtual device or printer.
391 void SetUseVirDev( bool bNew );
392
393 // Adding paragraph and table spacing at bottom
394 // of table cells.
395 void SetAddParaSpacingToTableCells( bool _bAddParaSpacingToTableCells );
396
397 // Former formatting of text lines with
398 // proportional line spacing or not.
399 void SetUseFormerLineSpacing( bool _bUseFormerLineSpacing );
400
401 // Former object positioning.
402 void SetUseFormerObjectPositioning( bool _bUseFormerObjPos );
403
404 void SetConsiderWrapOnObjPos( bool _bConsiderWrapOnObjPos );
405
406 void SetUseFormerTextWrapping( bool _bUseFormerTextWrapping );
407
408 void SetDoNotJustifyLinesWithManualBreak( bool _bDoNotJustifyLinesWithManualBreak );
409
410 void SetProtectForm( bool _bProtectForm );
411
412 void SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks );
413
414 void SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys);
415
416 void SetEmptyDbFieldHidesPara(bool bEmptyDbFieldHidesPara);
417
418 // DOCUMENT COMPATIBILITY FLAGS END
419
420 // Calls Idle-formatter of Layout.
421 void LayoutIdle();
422
423 const SwViewOption *GetViewOptions() const { return mpOpt.get(); }
424 virtual void ApplyViewOptions( const SwViewOption &rOpt );
425 void SetUIOptions( const SwViewOption &rOpt );
426 virtual void SetReadonlyOption(bool bSet); // Set readonly-bit of ViewOptions.
427 void SetPDFExportOption(bool bSet); // Set/reset PDF export mode.
428 void SetPrtFormatOption(bool bSet); // Set PrtFormat-Bit of ViewOptions.
429 void SetReadonlySelectionOption(bool bSet); // Change the selection mode in readonly docs.
430
431 const SwAccessibilityOptions* GetAccessibilityOptions() const { return mpAccOptions.get();}
432
433 static void SetShellRes( ShellResource* pRes ) { mpShellRes = pRes; }
434 static ShellResource* GetShellRes();
435
436 static weld::Window* CareChildWin(SwViewShell const & rVSh);
437 static void SetCareDialog(const std::shared_ptr<weld::Window>& rNew);
438 static weld::Window* GetCareDialog(SwViewShell const & rVSh)
439 { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : CareChildWin(rVSh); }
440
441 SfxViewShell *GetSfxViewShell() const { return mpSfxViewShell; }
442 void SetSfxViewShell(SfxViewShell *pNew) { mpSfxViewShell = pNew; }
443
444 // Selection of Draw Engine has been changed.
445 virtual void DrawSelChanged();
446
447 SwPagePreviewLayout* PagePreviewLayout();
448
449 /** adjust view options for page preview
450
451 Because page preview should show the document as it is printed -
452 page preview is print preview -, the view options are adjusted to the
453 same as for printing.
454
455 @param _rPrintOptions
456 input parameter - constant reference to print options, to which the
457 view option will be adjusted.
458 */
459 void AdjustOptionsForPagePreview( SwPrintData const& rPrintOptions );
460
461 bool IsViewLocked() const { return mbViewLocked; }
462 void LockView( bool b ) { mbViewLocked = b; }
463
464 inline void LockPaint();
465 void ImplLockPaint();
466 inline void UnlockPaint( bool bVirDev = false );
467 void ImplUnlockPaint( bool bVirDev );
468 bool IsPaintLocked() const { return mnLockPaint != 0; }
469
470 // Get/set DrawView and PageView.
471 bool HasDrawView() const;
472 void MakeDrawView();
473
474 // Are we dragging draw shapes around.
475 bool HasDrawViewDrag() const;
476
477 // DrawView may be used at UI.
478 SdrView *GetDrawView();
479 const SdrView *GetDrawView() const { return const_cast<SwViewShell*>(this)->GetDrawView(); }
480
481 // Take care that MarkList is up-to-date in any case (Bug 57153).
482 SdrView *GetDrawViewWithValidMarkList();
483
484 // Query attribute pool.
485 inline const SfxItemPool& GetAttrPool() const;
486 SfxItemPool& GetAttrPool();
487
488 bool IsPreview() const { return mbPreview; }
489
490 bool IsFrameView() const { return mbFrameView; }
491
492 // Invalidates pages and contents.
493 // When bSizeChanged==true, adds/removes
494 // headers and footers as necessary.
495 void InvalidateLayout(bool bSizeChanged);
496
497 const Size& GetBrowseBorder() const;
498 sal_Int32 GetBrowseWidth() const;
499 void SetBrowseBorder( const Size& rNew );
500
501 css::uno::Reference< css::accessibility::XAccessible > CreateAccessible();
502
503 css::uno::Reference< css::accessibility::XAccessible > CreateAccessiblePreview();
504
505 void ShowPreviewSelection( sal_uInt16 nSelPage );
506 void InvalidateAccessibleFocus();
507
508 // Apply Accessibility options.
509 void ApplyAccessibilityOptions(SvtAccessibilityOptions const & rAccessibilityOptions);
510
511 /** invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs
512
513 @param _pFromTextFrame
514 input parameter - paragraph frame, for which the relation CONTENT_FLOWS_FROM
515 has to be invalidated.
516 If NULL, no CONTENT_FLOWS_FROM relation has to be invalidated
517
518 @param _pToTextFrame
519 input parameter - paragraph frame, for which the relation CONTENT_FLOWS_TO
520 has to be invalidated.
521 If NULL, no CONTENT_FLOWS_TO relation has to be invalidated
522 */
523 void InvalidateAccessibleParaFlowRelation( const SwTextFrame* _pFromTextFrame,
524 const SwTextFrame* _pToTextFrame );
525
526 /** invalidate text selection for paragraphs
527 */
528 void InvalidateAccessibleParaTextSelection();
529
530 /** invalidate attributes for paragraphs and paragraph's characters
531
532 usage also for changes of the attributes of
533 paragraph's characters.
534
535 @param rTextFrame
536 input parameter - paragraph frame, whose attributes have changed
537 */
538 void InvalidateAccessibleParaAttrs( const SwTextFrame& rTextFrame );
539
540 SwAccessibleMap* GetAccessibleMap();
541
542 SwViewShell( SwViewShell&, vcl::Window *pWin, OutputDevice *pOut = nullptr,
543 long nFlags = 0 );
544 SwViewShell( SwDoc& rDoc, vcl::Window *pWin,
545 const SwViewOption *pOpt, OutputDevice *pOut = nullptr,
546 long nFlags = 0 );
547 virtual ~SwViewShell() override;
548
549 sal_Int32 GetPageNumAndSetOffsetForPDF( OutputDevice& rOut, const SwRect& rRect ) const;
550
551 bool IsInConstructor() const { return mbInConstructor; }
552
553 const BitmapEx& GetReplacementBitmap(bool bIsErrorState);
554 void DeleteReplacementBitmaps();
555
556 const SwPostItMgr* GetPostItMgr() const { return const_cast<SwViewShell*>(this)->GetPostItMgr(); }
557 SwPostItMgr* GetPostItMgr();
558
559 /// Acts both for headers / footers, depending on the bShow(Header|Footer)Separator flags
560 void ToggleHeaderFooterEdit();
561 /// Acts both for headers / footers, depending on the bShow(Header|Footer)Separator flags
562 bool IsHeaderFooterEdit() const { return mbHeaderFooterEdit; }
563 bool IsShowHeaderFooterSeparator( FrameControlType eControl ) { return (eControl == FrameControlType::Header)? mbShowHeaderSeparator: mbShowFooterSeparator; }
564 virtual void SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow );
565 bool IsSelectAll() const { return mbSelectAll; }
566
567 void setOutputToWindow(bool bOutputToWindow);
568 bool isOutputToWindow() const;
569
570 virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
571};
572
573// manages global ShellPointer
574class CurrShell
575{
576public:
577 SwViewShell *pPrev;
578 SwRootFrame *pRoot;
579
580 CurrShell( SwViewShell *pNew );
581 ~CurrShell();
582};
583
584inline void SwViewShell::ResetInvalidRect()
585{
586 maInvalidRect.Clear();
587}
588
589inline void SwViewShell::StartAction()
590{
591 if ( !mnStartAction++ )
592 ImplStartAction();
593}
594inline void SwViewShell::EndAction( const bool bIdleEnd )
595{
596 if( 0 == (mnStartAction - 1) )
597 ImplEndAction( bIdleEnd );
598 --mnStartAction;
599}
600
601inline void SwViewShell::LockPaint()
602{
603 if ( !mnLockPaint++ )
604 ImplLockPaint();
605}
606inline void SwViewShell::UnlockPaint( bool bVirDev )
607{
608 if ( 0 == --mnLockPaint )
609 ImplUnlockPaint( bVirDev );
610}
611inline const SfxItemPool& SwViewShell::GetAttrPool() const
612{
613 return const_cast<SwViewShell*>(this)->GetAttrPool();
614}
615
616#endif // INCLUDED_SW_INC_VIEWSH_HXX
617
618/* 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)
14
Assuming the condition is true
15
Taking true branch
40 delete this;
16
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