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 viewsh.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/viewsh.cxx

/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.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 <com/sun/star/accessibility/XAccessible.hpp>
21#include <sfx2/viewfrm.hxx>
22#include <sfx2/progress.hxx>
23#include <svx/srchdlg.hxx>
24#include <sfx2/viewsh.hxx>
25#include <sfx2/ipclient.hxx>
26#include <sal/log.hxx>
27#include <drawdoc.hxx>
28#include <swwait.hxx>
29#include <crsrsh.hxx>
30#include <doc.hxx>
31#include <IDocumentDeviceAccess.hxx>
32#include <IDocumentDrawModelAccess.hxx>
33#include <IDocumentOutlineNodes.hxx>
34#include <IDocumentFieldsAccess.hxx>
35#include <IDocumentLayoutAccess.hxx>
36#include <IDocumentState.hxx>
37#include <rootfrm.hxx>
38#include <pagefrm.hxx>
39#include <cntfrm.hxx>
40#include <viewimp.hxx>
41#include <frmtool.hxx>
42#include <viewopt.hxx>
43#include <dview.hxx>
44#include <swregion.hxx>
45#include <hints.hxx>
46#include <docufld.hxx>
47#include <txtfrm.hxx>
48#include <layact.hxx>
49#include <mdiexp.hxx>
50#include <fntcache.hxx>
51#include <ptqueue.hxx>
52#include <docsh.hxx>
53#include <pagedesc.hxx>
54#include <ndole.hxx>
55#include <ndindex.hxx>
56#include <accmap.hxx>
57#include <vcl/bitmapex.hxx>
58#include <svtools/accessibilityoptions.hxx>
59#include <accessibilityoptions.hxx>
60#include <strings.hrc>
61#include <bitmaps.hlst>
62#include <pagepreviewlayout.hxx>
63#include <sortedobjs.hxx>
64#include <anchoredobject.hxx>
65#include <DocumentSettingManager.hxx>
66
67#include <unotxdoc.hxx>
68#include <view.hxx>
69#include <PostItMgr.hxx>
70#include <unotools/configmgr.hxx>
71#include <vcl/virdev.hxx>
72#include <vcl/svapp.hxx>
73#include <svx/sdrpaintwindow.hxx>
74#include <svx/sdr/overlay/overlaymanager.hxx>
75#include <svx/sdrpagewindow.hxx>
76#include <svx/svdpagv.hxx>
77#include <comphelper/lok.hxx>
78#include <sfx2/lokhelper.hxx>
79
80#if !HAVE_FEATURE_DESKTOP1
81#include <vcl/sysdata.hxx>
82#endif
83
84bool SwViewShell::mbLstAct = false;
85ShellResource *SwViewShell::mpShellRes = nullptr;
86vcl::DeleteOnDeinit<std::shared_ptr<weld::Window>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Window>);
87
88static bool bInSizeNotify = false;
89
90
91using namespace ::com::sun::star;
92
93void SwViewShell::SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow ) {
94
95 //tdf#118621 - Optionally disable floating header/footer menu
96 if ( bShow )
97 bShow = GetViewOptions()->IsUseHeaderFooterMenu();
98
99 if ( eControl == FrameControlType::Header )
100 mbShowHeaderSeparator = bShow;
101 else
102 mbShowFooterSeparator = bShow;
103}
104
105void SwViewShell::ToggleHeaderFooterEdit()
106{
107 mbHeaderFooterEdit = !mbHeaderFooterEdit;
108 if ( !mbHeaderFooterEdit )
109 {
110 SetShowHeaderFooterSeparator( FrameControlType::Header, false );
111 SetShowHeaderFooterSeparator( FrameControlType::Footer, false );
112 }
113
114 // Avoid corner case
115 if ( ( GetViewOptions()->IsUseHeaderFooterMenu() ) &&
116 ( !IsShowHeaderFooterSeparator( FrameControlType::Header ) &&
117 !IsShowHeaderFooterSeparator( FrameControlType::Footer ) ) )
118 {
119 mbHeaderFooterEdit = false;
120 }
121
122 // Repaint everything
123 GetWin()->Invalidate();
124}
125
126void SwViewShell::setOutputToWindow(bool bOutputToWindow)
127{
128 mbOutputToWindow = bOutputToWindow;
129}
130
131bool SwViewShell::isOutputToWindow() const
132{
133 return mbOutputToWindow;
134}
135
136void SwViewShell::dumpAsXml(xmlTextWriterPtr pWriter) const
137{
138 xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SwViewShell"));
139 xmlTextWriterEndElement(pWriter);
140}
141
142static void
143lcl_PaintTransparentFormControls(SwViewShell const & rShell, SwRect const& rRect)
144{
145 // Direct paint has been performed: the background of transparent child
146 // windows has been painted, so need to paint the child windows now.
147 if (rShell.GetWin())
148 {
149 vcl::Window& rWindow = *(rShell.GetWin());
150 const tools::Rectangle aRectanglePixel(rShell.GetOut()->LogicToPixel(rRect.SVRect()));
151 PaintTransparentChildren(rWindow, aRectanglePixel);
152 }
153}
154
155// #i72754# 2nd set of Pre/PostPaints
156// This time it uses the lock counter (mPrePostPaintRegions empty/non-empty) to allow only one activation
157// and deactivation and mpPrePostOutDev to remember the OutDev from the BeginDrawLayers
158// call. That way, all places where paint take place can be handled the same way, even
159// when calling other paint methods. This is the case at the places where SW paints
160// buffered into VDevs to avoid flicker. It is in general problematic and should be
161// solved once using the BufferedOutput functionality of the DrawView.
162
163void SwViewShell::PrePaint()
164{
165 // forward PrePaint event from VCL Window to DrawingLayer
166 if(HasDrawView())
167 {
168 Imp()->GetDrawView()->PrePaint();
169 }
170}
171
172void SwViewShell::DLPrePaint2(const vcl::Region& rRegion)
173{
174 if(mPrePostPaintRegions.empty())
175 {
176 mPrePostPaintRegions.push( rRegion );
177 // #i75172# ensure DrawView to use DrawingLayer bufferings
178 if ( !HasDrawView() )
179 MakeDrawView();
180
181 // Prefer window; if not available, get mpOut (e.g. printer)
182 const bool bWindow = GetWin() && !comphelper::LibreOfficeKit::isActive() && !isOutputToWindow();
183 mpPrePostOutDev = bWindow ? GetWin(): GetOut();
184
185 // #i74769# use SdrPaintWindow now direct
186 mpTargetPaintWindow = Imp()->GetDrawView()->BeginDrawLayers(mpPrePostOutDev, rRegion);
187 OSL_ENSURE(mpTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)")do { if (true && (!(mpTargetPaintWindow))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "187" ": "), "%s", "BeginDrawLayers: Got no SdrPaintWindow (!)"
); } } while (false)
;
188
189 // #i74769# if prerender, save OutDev and redirect to PreRenderDevice
190 if(mpTargetPaintWindow->GetPreRenderDevice())
191 {
192 mpBufferedOut = mpOut;
193 mpOut = &(mpTargetPaintWindow->GetTargetOutputDevice());
194 }
195 else if (isOutputToWindow())
196 // In case mpOut is used without buffering and we're not printing, need to set clipping.
197 mpOut->SetClipRegion(rRegion);
198
199 // remember original paint MapMode for wrapped FlyFrame paints
200 maPrePostMapMode = mpOut->GetMapMode();
201 }
202 else
203 {
204 // region needs to be updated to the given one
205 if( mPrePostPaintRegions.top() != rRegion )
206 Imp()->GetDrawView()->UpdateDrawLayersRegion(mpPrePostOutDev, rRegion);
207 mPrePostPaintRegions.push( rRegion );
208 }
209}
210
211void SwViewShell::DLPostPaint2(bool bPaintFormLayer)
212{
213 OSL_ENSURE(!mPrePostPaintRegions.empty(), "SwViewShell::DLPostPaint2: Pre/PostPaint encapsulation broken (!)")do { if (true && (!(!mPrePostPaintRegions.empty()))) {
sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "213" ": "), "%s", "SwViewShell::DLPostPaint2: Pre/PostPaint encapsulation broken (!)"
); } } while (false)
;
214
215 if( mPrePostPaintRegions.size() > 1 )
216 {
217 vcl::Region current = std::move(mPrePostPaintRegions.top());
218 mPrePostPaintRegions.pop();
219 if( current != mPrePostPaintRegions.top())
220 Imp()->GetDrawView()->UpdateDrawLayersRegion(mpPrePostOutDev, mPrePostPaintRegions.top());
221 return;
222 }
223 mPrePostPaintRegions.pop(); // clear
224 if(nullptr != mpTargetPaintWindow)
225 {
226 // #i74769# restore buffered OutDev
227 if(mpTargetPaintWindow->GetPreRenderDevice())
228 {
229 mpOut = mpBufferedOut;
230 }
231
232 // #i74769# use SdrPaintWindow now direct
233 Imp()->GetDrawView()->EndDrawLayers(*mpTargetPaintWindow, bPaintFormLayer);
234 mpTargetPaintWindow = nullptr;
235 }
236}
237// end of Pre/PostPaints
238
239void SwViewShell::ImplEndAction( const bool bIdleEnd )
240{
241 // Nothing to do for the printer?
242 if ( !GetWin() || IsPreview() )
9
Assuming the condition is false
10
Taking false branch
243 {
244 mbPaintWorks = true;
245 UISizeNotify();
246 // tdf#101464 print preview may generate events if another view shell
247 // performs layout...
248 if (IsPreview() && Imp()->IsAccessible())
249 {
250 Imp()->FireAccessibleEvents();
251 }
252 return;
253 }
254
255 mbInEndAction = true;
256 //will this put the EndAction of the last shell in the sequence?
257
258 SwViewShell::mbLstAct = true;
259 for(SwViewShell& rShell : GetRingContainer())
260 {
261 if(&rShell != this && rShell.ActionPend())
262 {
263 SwViewShell::mbLstAct = false;
264 break;
265 }
266 }
267
268 const bool bIsShellForCheckViewLayout = ( this == GetLayout()->GetCurrShell() );
11
Assuming the condition is false
269
270 CurrShell aCurr( this );
271 if ( Imp()->HasDrawView() && !Imp()->GetDrawView()->areMarkHandlesHidden() )
272 Imp()->StartAction();
273
274 if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
12
Assuming the condition is false
275 Imp()->DelRegion();
276
277 const bool bExtraData = ::IsExtraData( GetDoc() );
278
279 if ( !bIdleEnd
12.1
'bIdleEnd' is false
12.1
'bIdleEnd' is false
12.1
'bIdleEnd' is false
12.1
'bIdleEnd' is false
12.1
'bIdleEnd' is false
)
13
Taking true branch
280 {
281 SwLayAction aAction( GetLayout(), Imp() );
282 aAction.SetComplete( false );
283 if ( mnLockPaint )
14
Assuming field 'mnLockPaint' is 0
15
Taking false branch
284 aAction.SetPaint( false );
285 aAction.Action(GetWin());
286 }
287
288 if ( bIsShellForCheckViewLayout
15.1
'bIsShellForCheckViewLayout' is false
15.1
'bIsShellForCheckViewLayout' is false
15.1
'bIsShellForCheckViewLayout' is false
15.1
'bIsShellForCheckViewLayout' is false
15.1
'bIsShellForCheckViewLayout' is false
)
16
Taking false branch
289 GetLayout()->CheckViewLayout( GetViewOptions(), &maVisArea );
290
291 //If we don't call Paints, we wait for the Paint of the system.
292 //Then the clipping is set correctly; e.g. shifting of a Draw object
293 if ( Imp()->GetRegion() ||
17
Assuming the condition is true
294 maInvalidRect.HasArea() ||
295 bExtraData )
296 {
297 if ( !mnLockPaint
17.1
Field 'mnLockPaint' is 0
17.1
Field 'mnLockPaint' is 0
17.1
Field 'mnLockPaint' is 0
17.1
Field 'mnLockPaint' is 0
17.1
Field 'mnLockPaint' is 0
)
18
Taking true branch
298 {
299 SolarMutexGuard aGuard;
300
301 bool bPaintsFromSystem = maInvalidRect.HasArea();
302 GetWin()->PaintImmediately();
303 if ( maInvalidRect.HasArea() )
19
Taking false branch
304 {
305 if ( bPaintsFromSystem )
306 Imp()->AddPaintRect( maInvalidRect );
307
308 ResetInvalidRect();
309 bPaintsFromSystem = true;
310 }
311 mbPaintWorks = true;
312
313 std::unique_ptr<SwRegionRects> pRegion = std::move(Imp()->m_pRegion);
314
315 //JP 27.11.97: what hid the selection, must also Show it,
316 // else we get Paint errors!
317 // e.g. additional mode, page half visible vertically, in the
318 // middle a selection and with another cursor jump to left
319 // right border. Without ShowCursor the selection disappears.
320 bool bShowCursor = pRegion && dynamic_cast<const SwCursorShell*>(this) != nullptr;
321 if( bShowCursor
19.1
'bShowCursor' is true
19.1
'bShowCursor' is true
19.1
'bShowCursor' is true
19.1
'bShowCursor' is true
19.1
'bShowCursor' is true
)
20
Taking true branch
322 static_cast<SwCursorShell*>(this)->HideCursors();
323
324 if ( pRegion )
21
Taking true branch
325 {
326 SwRootFrame* pCurrentLayout = GetLayout();
327
328 //First Invert then Compress, never the other way round!
329 pRegion->Invert();
330
331 pRegion->Compress();
332
333 ScopedVclPtr<VirtualDevice> pVout;
334 while ( !pRegion->empty() )
22
Assuming the condition is true
23
Loop condition is true. Entering loop body
335 {
336 SwRect aRect( pRegion->back() );
337 pRegion->pop_back();
338
339 bool bPaint = true;
340 if ( IsEndActionByVirDev() )
24
Assuming the condition is true
25
Taking true branch
341 {
342 //create virtual device and set.
343 if ( !pVout )
26
Taking true branch
344 pVout = VclPtr<VirtualDevice>::Create( *GetOut() );
27
Calling 'VclPtr::Create'
29
Returned allocated memory
30
Calling implicit destructor for 'VclPtr<VirtualDevice>'
31
Calling '~Reference'
38
Returning from '~Reference'
39
Returning from destructor for 'VclPtr<VirtualDevice>'
345 MapMode aMapMode( GetOut()->GetMapMode() );
346 pVout->SetMapMode( aMapMode );
40
Calling 'VclPtr::operator->'
347
348 bool bSizeOK = true;
349
350 tools::Rectangle aTmp1( aRect.SVRect() );
351 aTmp1 = GetOut()->LogicToPixel( aTmp1 );
352 tools::Rectangle aTmp2( GetOut()->PixelToLogic( aTmp1 ) );
353 if ( aTmp2.Left() > aRect.Left() )
354 aTmp1.SetLeft( std::max( 0L, aTmp1.Left() - 1 ) );
355 if ( aTmp2.Top() > aRect.Top() )
356 aTmp1.SetTop( std::max( 0L, aTmp1.Top() - 1 ) );
357 aTmp1.AdjustRight(1 );
358 aTmp1.AdjustBottom(1 );
359 aTmp1 = GetOut()->PixelToLogic( aTmp1 );
360 aRect = SwRect( aTmp1 );
361
362 const Size aTmp( pVout->GetOutputSize() );
363 if ( aTmp.Height() < aRect.Height() ||
364 aTmp.Width() < aRect.Width() )
365 {
366 bSizeOK = pVout->SetOutputSize( aRect.SSize() );
367 }
368 if ( bSizeOK )
369 {
370 bPaint = false;
371
372 // --> OD 2007-07-26 #i79947#
373 // #i72754# start Pre/PostPaint encapsulation before mpOut is changed to the buffering VDev
374 const vcl::Region aRepaintRegion(aRect.SVRect());
375 DLPrePaint2(aRepaintRegion);
376 // <--
377
378 OutputDevice *pOld = GetOut();
379 pVout->SetLineColor( pOld->GetLineColor() );
380 pVout->SetFillColor( pOld->GetFillColor() );
381 Point aOrigin( aRect.Pos() );
382 aOrigin.setX( -aOrigin.X() ); aOrigin.setY( -aOrigin.Y() );
383 aMapMode.SetOrigin( aOrigin );
384 pVout->SetMapMode( aMapMode );
385
386 mpOut = pVout.get();
387 if ( bPaintsFromSystem )
388 PaintDesktop(*mpOut, aRect);
389 pCurrentLayout->PaintSwFrame( *mpOut, aRect );
390 pOld->DrawOutDev( aRect.Pos(), aRect.SSize(),
391 aRect.Pos(), aRect.SSize(), *pVout );
392 mpOut = pOld;
393
394 // #i72754# end Pre/PostPaint encapsulation when mpOut is back and content is painted
395 DLPostPaint2(true);
396 }
397 }
398 if ( bPaint )
399 {
400 if (GetWin()->SupportsDoubleBuffering())
401 InvalidateWindows(aRect.SVRect());
402 else
403 {
404 // #i75172# begin DrawingLayer paint
405 // need to do begin/end DrawingLayer preparation for each single rectangle of the
406 // repaint region. I already tried to prepare only once for the whole Region. This
407 // seems to work (and does technically) but fails with transparent objects. Since the
408 // region given to BeginDarwLayers() defines the clip region for DrawingLayer paint,
409 // transparent objects in the single rectangles will indeed be painted multiple times.
410 DLPrePaint2(vcl::Region(aRect.SVRect()));
411
412 if ( bPaintsFromSystem )
413 PaintDesktop(*GetOut(), aRect);
414 if (!comphelper::LibreOfficeKit::isActive())
415 pCurrentLayout->PaintSwFrame( *mpOut, aRect );
416 else
417 pCurrentLayout->GetCurrShell()->InvalidateWindows(aRect.SVRect());
418
419 // #i75172# end DrawingLayer paint
420 DLPostPaint2(true);
421 }
422 }
423
424 lcl_PaintTransparentFormControls(*this, aRect); // i#107365
425 }
426 }
427 if( bShowCursor )
428 static_cast<SwCursorShell*>(this)->ShowCursors( true );
429 }
430 else
431 {
432 Imp()->DelRegion();
433 mbPaintWorks = true;
434 }
435 }
436 else
437 mbPaintWorks = true;
438
439 mbInEndAction = false;
440 SwViewShell::mbLstAct = false;
441 Imp()->EndAction();
442
443 //We artificially end the action here to enable the automatic scrollbars
444 //to adjust themselves correctly
445 //EndAction sends a Notify, and that must call Start-/EndAction to
446 //adjust the scrollbars correctly
447 --mnStartAction;
448 UISizeNotify();
449 ++mnStartAction;
450
451 if( Imp()->IsAccessible() )
452 Imp()->FireAccessibleEvents();
453}
454
455void SwViewShell::ImplStartAction()
456{
457 mbPaintWorks = false;
458 Imp()->StartAction();
459}
460
461void SwViewShell::ImplLockPaint()
462{
463 if ( GetWin() && GetWin()->IsVisible() )
464 GetWin()->EnablePaint( false ); //Also cut off the controls.
465 Imp()->LockPaint();
466}
467
468void SwViewShell::ImplUnlockPaint( bool bVirDev )
469{
470 CurrShell aCurr( this );
471 if ( GetWin() && GetWin()->IsVisible() )
472 {
473 if ( (bInSizeNotify || bVirDev ) && VisArea().HasArea() )
474 {
475 //Refresh with virtual device to avoid flickering.
476 VclPtrInstance<VirtualDevice> pVout( *mpOut );
477 pVout->SetMapMode( mpOut->GetMapMode() );
478 Size aSize( VisArea().SSize() );
479 aSize.AdjustWidth(20 );
480 aSize.AdjustHeight(20 );
481 if( pVout->SetOutputSize( aSize ) )
482 {
483 GetWin()->EnablePaint( true );
484 GetWin()->Validate();
485
486 Imp()->UnlockPaint();
487 pVout->SetLineColor( mpOut->GetLineColor() );
488 pVout->SetFillColor( mpOut->GetFillColor() );
489
490 // #i72754# start Pre/PostPaint encapsulation before mpOut is changed to the buffering VDev
491 const vcl::Region aRepaintRegion(VisArea().SVRect());
492 DLPrePaint2(aRepaintRegion);
493
494 OutputDevice *pOld = mpOut;
495 mpOut = pVout.get();
496 Paint(*mpOut, VisArea().SVRect());
497 mpOut = pOld;
498 mpOut->DrawOutDev( VisArea().Pos(), aSize,
499 VisArea().Pos(), aSize, *pVout );
500
501 // #i72754# end Pre/PostPaint encapsulation when mpOut is back and content is painted
502 DLPostPaint2(true);
503
504 lcl_PaintTransparentFormControls(*this, VisArea()); // fdo#63949
505 }
506 else
507 {
508 Imp()->UnlockPaint();
509 GetWin()->EnablePaint( true );
510 GetWin()->Invalidate( InvalidateFlags::Children );
511 }
512 pVout.disposeAndClear();
513 }
514 else
515 {
516 Imp()->UnlockPaint();
517 GetWin()->EnablePaint( true );
518 GetWin()->Invalidate( InvalidateFlags::Children );
519 }
520 }
521 else
522 Imp()->UnlockPaint();
523}
524
525bool SwViewShell::AddPaintRect( const SwRect & rRect )
526{
527 bool bRet = false;
528 for(SwViewShell& rSh : GetRingContainer())
529 {
530 if( rSh.Imp() )
531 {
532 if ( rSh.IsPreview() && rSh.GetWin() )
533 ::RepaintPagePreview( &rSh, rRect );
534 else
535 bRet |= rSh.Imp()->AddPaintRect( rRect );
536 }
537 }
538 return bRet;
539}
540
541void SwViewShell::InvalidateWindows( const SwRect &rRect )
542{
543 if ( Imp()->IsCalcLayoutProgress() )
544 return;
545
546 for(SwViewShell& rSh : GetRingContainer())
547 {
548 if ( rSh.GetWin() )
549 {
550 if ( rSh.IsPreview() )
551 ::RepaintPagePreview( &rSh, rRect );
552 // In case of tiled rendering, invalidation is wanted even if
553 // the rectangle is outside the visual area.
554 else if ( rSh.VisArea().IsOver( rRect ) || comphelper::LibreOfficeKit::isActive() )
555 rSh.GetWin()->Invalidate( rRect.SVRect() );
556 }
557 }
558}
559
560const SwRect& SwViewShell::VisArea() const
561{
562 // when using the tiled rendering, consider the entire document as our
563 // visible area
564 return comphelper::LibreOfficeKit::isActive()? GetLayout()->getFrameArea(): maVisArea;
565}
566
567void SwViewShell::MakeVisible( const SwRect &rRect )
568{
569 if ( !(!VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareDialog(*this)) )
570 return;
571
572 if ( IsViewLocked() )
573 return;
574
575 if( mpWin )
576 {
577 const SwFrame* pRoot = GetLayout();
578 int nLoopCnt = 3;
579 long nOldH;
580 do{
581 nOldH = pRoot->getFrameArea().Height();
582 StartAction();
583 ScrollMDI( this, rRect, USHRT_MAX(32767 *2 +1), USHRT_MAX(32767 *2 +1) );
584 EndAction();
585 } while( nOldH != pRoot->getFrameArea().Height() && nLoopCnt-- );
586 }
587#if OSL_DEBUG_LEVEL1 > 0
588 else
589 {
590 //MA: 04. Nov. 94, no one needs this, does one?
591 OSL_ENSURE( false, "Is MakeVisible still needed for printers?" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "591" ": "), "%s", "Is MakeVisible still needed for printers?"
); } } while (false)
;
592 }
593
594#endif
595}
596
597weld::Window* SwViewShell::CareChildWin(SwViewShell const & rVSh)
598{
599 if (!rVSh.mpSfxViewShell)
600 return nullptr;
601#if HAVE_FEATURE_DESKTOP1
602 const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId();
603 SfxViewFrame* pVFrame = rVSh.mpSfxViewShell->GetViewFrame();
604 SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId );
605 if (!pChWin)
606 return nullptr;
607 weld::DialogController* pController = pChWin->GetController().get();
608 if (!pController)
609 return nullptr;
610 weld::Window* pWin = pController->getDialog();
611 if (pWin && pWin->get_visible())
612 return pWin;
613#endif
614 return nullptr;
615}
616
617Point SwViewShell::GetPagePos( sal_uInt16 nPageNum ) const
618{
619 return GetLayout()->GetPagePos( nPageNum );
620}
621
622sal_uInt16 SwViewShell::GetNumPages() const
623{
624 //It is possible that no layout exists when the method from
625 //root-Ctor is called.
626 return GetLayout() ? GetLayout()->GetPageNum() : 0;
627}
628
629bool SwViewShell::IsDummyPage( sal_uInt16 nPageNum ) const
630{
631 return GetLayout() && GetLayout()->IsDummyPage( nPageNum );
632}
633
634/**
635 * Forces update of each field.
636 * It notifies all fields with pNewHt. If that is 0 (default), the field
637 * type is sent (???).
638 * @param[in] bCloseDB Passed in to GetDoc()->UpdateFields. [TODO] Purpose???
639 */
640void SwViewShell::UpdateFields(bool bCloseDB)
641{
642 CurrShell aCurr( this );
643
644 bool bCursor = dynamic_cast<const SwCursorShell*>( this ) != nullptr;
645 if ( bCursor )
646 static_cast<SwCursorShell*>(this)->StartAction();
647 else
648 StartAction();
649
650 GetDoc()->getIDocumentFieldsAccess().UpdateFields(bCloseDB);
651
652 if ( bCursor )
653 static_cast<SwCursorShell*>(this)->EndAction();
654 else
655 EndAction();
656}
657
658/** update all charts for which any table exists */
659void SwViewShell::UpdateAllCharts()
660{
661 CurrShell aCurr( this );
662 // Start-/EndAction handled in the SwDoc-Method!
663 GetDoc()->UpdateAllCharts();
664}
665
666bool SwViewShell::HasCharts() const
667{
668 bool bRet = false;
669 SwNodeIndex aIdx( *GetDoc()->GetNodes().GetEndOfAutotext().
670 StartOfSectionNode(), 1 );
671 while (aIdx.GetNode().GetStartNode())
672 {
673 ++aIdx;
674 const SwOLENode *pNd = aIdx.GetNode().GetOLENode();
675 if( pNd && !pNd->GetChartTableName().isEmpty() )
676 {
677 bRet = true;
678 break;
679 }
680 }
681 return bRet;
682}
683
684void SwViewShell::LayoutIdle()
685{
686 if( !mpOpt->IsIdle() || !GetWin() || HasDrawViewDrag() )
687 return;
688
689 //No idle when printing is going on.
690 for(const SwViewShell& rSh : GetRingContainer())
691 {
692 if ( !rSh.GetWin() )
693 return;
694 }
695
696 CurrShell aCurr( this );
697
698#ifdef DBG_UTIL
699 // If Test5 has been set, the IdleFormatter is disabled.
700 if( mpOpt->IsTest5() )
701 return;
702#endif
703
704 {
705 // Preserve top of the text frame cache.
706 SwSaveSetLRUOfst aSaveLRU;
707 // #125243# there are lots of stacktraces indicating that Imp() returns NULL
708 // this SwViewShell seems to be invalid - but it's not clear why
709 // this return is only a workaround!
710 OSL_ENSURE(Imp(), "SwViewShell already deleted?")do { if (true && (!(Imp()))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "710" ": "), "%s", "SwViewShell already deleted?"); } } while
(false)
;
711 if(!Imp())
712 return;
713 SwLayIdle aIdle( GetLayout(), Imp() );
714 }
715}
716
717static void lcl_InvalidateAllContent( SwViewShell& rSh, SwInvalidateFlags nInv )
718{
719 bool bCursor = dynamic_cast<const SwCursorShell*>( &rSh) != nullptr;
720 if ( bCursor )
721 static_cast<SwCursorShell&>(rSh).StartAction();
722 else
723 rSh.StartAction();
724 rSh.GetLayout()->InvalidateAllContent( nInv );
725 if ( bCursor )
726 static_cast<SwCursorShell&>(rSh).EndAction();
727 else
728 rSh.EndAction();
729
730 rSh.GetDoc()->getIDocumentState().SetModified();
731}
732
733/** local method to invalidate/re-calculate positions of floating screen
734 * objects (Writer fly frame and drawing objects), which are anchored
735 * to paragraph or to character. #i11860#
736 */
737static void lcl_InvalidateAllObjPos( SwViewShell &_rSh )
738{
739 const bool bIsCursorShell = dynamic_cast<const SwCursorShell*>( &_rSh) != nullptr;
740 if ( bIsCursorShell )
741 static_cast<SwCursorShell&>(_rSh).StartAction();
742 else
743 _rSh.StartAction();
744
745 _rSh.GetLayout()->InvalidateAllObjPos();
746
747 if ( bIsCursorShell )
748 static_cast<SwCursorShell&>(_rSh).EndAction();
749 else
750 _rSh.EndAction();
751
752 _rSh.GetDoc()->getIDocumentState().SetModified();
753}
754
755void SwViewShell::SetParaSpaceMax( bool bNew )
756{
757 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
758 if( rIDSA.get(DocumentSettingId::PARA_SPACE_MAX) != bNew )
759 {
760 SwWait aWait( *GetDoc()->GetDocShell(), true );
761 rIDSA.set(DocumentSettingId::PARA_SPACE_MAX, bNew );
762 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
763 lcl_InvalidateAllContent( *this, nInv );
764 }
765}
766
767void SwViewShell::SetParaSpaceMaxAtPages( bool bNew )
768{
769 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
770 if( rIDSA.get(DocumentSettingId::PARA_SPACE_MAX_AT_PAGES) != bNew )
771 {
772 SwWait aWait( *GetDoc()->GetDocShell(), true );
773 rIDSA.set(DocumentSettingId::PARA_SPACE_MAX_AT_PAGES, bNew );
774 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
775 lcl_InvalidateAllContent( *this, nInv );
776 }
777}
778
779void SwViewShell::SetTabCompat( bool bNew )
780{
781 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
782 if( rIDSA.get(DocumentSettingId::TAB_COMPAT) != bNew )
783 {
784 SwWait aWait( *GetDoc()->GetDocShell(), true );
785 rIDSA.set(DocumentSettingId::TAB_COMPAT, bNew );
786 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
787 lcl_InvalidateAllContent( *this, nInv );
788 }
789}
790
791void SwViewShell::SetAddExtLeading( bool bNew )
792{
793 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
794 if ( rIDSA.get(DocumentSettingId::ADD_EXT_LEADING) != bNew )
795 {
796 SwWait aWait( *GetDoc()->GetDocShell(), true );
797 rIDSA.set(DocumentSettingId::ADD_EXT_LEADING, bNew );
798 SwDrawModel* pTmpDrawModel = getIDocumentDrawModelAccess().GetDrawModel();
799 if ( pTmpDrawModel )
800 pTmpDrawModel->SetAddExtLeading( bNew );
801 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
802 lcl_InvalidateAllContent( *this, nInv );
803 }
804}
805
806void SwViewShell::SetUseVirDev( bool bNewVirtual )
807{
808 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
809 if ( rIDSA.get(DocumentSettingId::USE_VIRTUAL_DEVICE) != bNewVirtual )
810 {
811 SwWait aWait( *GetDoc()->GetDocShell(), true );
812 // this sets the flag at the document and calls PrtDataChanged
813 IDocumentDeviceAccess& rIDDA = getIDocumentDeviceAccess();
814 rIDDA.setReferenceDeviceType( bNewVirtual, true );
815 }
816}
817
818/** Sets if paragraph and table spacing is added at bottom of table cells.
819 * #106629#
820 * @param[in] (bool) setting of the new value
821 */
822void SwViewShell::SetAddParaSpacingToTableCells( bool _bAddParaSpacingToTableCells )
823{
824 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
825 if (rIDSA.get(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS) != _bAddParaSpacingToTableCells
826 || rIDSA.get(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS) != _bAddParaSpacingToTableCells)
827 {
828 SwWait aWait( *GetDoc()->GetDocShell(), true );
829 rIDSA.set(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS, _bAddParaSpacingToTableCells );
830 // note: the dialog can't change the value to indeterminate, so only false/false and true/true
831 rIDSA.set(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS, _bAddParaSpacingToTableCells );
832 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea;
833 lcl_InvalidateAllContent( *this, nInv );
834 }
835}
836
837/**
838 * Sets if former formatting of text lines with proportional line spacing should used.
839 * #i11859#
840 * @param[in] (bool) setting of the new value
841 */
842void SwViewShell::SetUseFormerLineSpacing( bool _bUseFormerLineSpacing )
843{
844 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
845 if ( rIDSA.get(DocumentSettingId::OLD_LINE_SPACING) != _bUseFormerLineSpacing )
846 {
847 SwWait aWait( *GetDoc()->GetDocShell(), true );
848 rIDSA.set(DocumentSettingId::OLD_LINE_SPACING, _bUseFormerLineSpacing );
849 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea;
850 lcl_InvalidateAllContent( *this, nInv );
851 }
852}
853
854/**
855 * Sets IDocumentSettingAccess if former object positioning should be used.
856 * #i11860#
857 * @param[in] (bool) setting the new value
858 */
859void SwViewShell::SetUseFormerObjectPositioning( bool _bUseFormerObjPos )
860{
861 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
862 if ( rIDSA.get(DocumentSettingId::USE_FORMER_OBJECT_POS) != _bUseFormerObjPos )
863 {
864 SwWait aWait( *GetDoc()->GetDocShell(), true );
865 rIDSA.set(DocumentSettingId::USE_FORMER_OBJECT_POS, _bUseFormerObjPos );
866 lcl_InvalidateAllObjPos( *this );
867 }
868}
869
870// #i28701#
871void SwViewShell::SetConsiderWrapOnObjPos( bool _bConsiderWrapOnObjPos )
872{
873 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
874 if ( rIDSA.get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) != _bConsiderWrapOnObjPos )
875 {
876 SwWait aWait( *GetDoc()->GetDocShell(), true );
877 rIDSA.set(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION, _bConsiderWrapOnObjPos );
878 lcl_InvalidateAllObjPos( *this );
879 }
880}
881
882void SwViewShell::SetUseFormerTextWrapping( bool _bUseFormerTextWrapping )
883{
884 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
885 if ( rIDSA.get(DocumentSettingId::USE_FORMER_TEXT_WRAPPING) != _bUseFormerTextWrapping )
886 {
887 SwWait aWait( *GetDoc()->GetDocShell(), true );
888 rIDSA.set(DocumentSettingId::USE_FORMER_TEXT_WRAPPING, _bUseFormerTextWrapping );
889 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
890 lcl_InvalidateAllContent( *this, nInv );
891 }
892}
893
894// #i45491#
895void SwViewShell::SetDoNotJustifyLinesWithManualBreak( bool _bDoNotJustifyLinesWithManualBreak )
896{
897 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
898 if ( rIDSA.get(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK) != _bDoNotJustifyLinesWithManualBreak )
899 {
900 SwWait aWait( *GetDoc()->GetDocShell(), true );
901 rIDSA.set(DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, _bDoNotJustifyLinesWithManualBreak );
902 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
903 lcl_InvalidateAllContent( *this, nInv );
904 }
905}
906
907void SwViewShell::SetProtectForm( bool _bProtectForm )
908{
909 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
910 rIDSA.set(DocumentSettingId::PROTECT_FORM, _bProtectForm );
911}
912
913void SwViewShell::SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks )
914{
915 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
916 if (rIDSA.get(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS) != _bMsWordCompTrailingBlanks)
917 {
918 SwWait aWait(*GetDoc()->GetDocShell(), true);
919 rIDSA.set(DocumentSettingId::MS_WORD_COMP_TRAILING_BLANKS, _bMsWordCompTrailingBlanks);
920 const SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Size | SwInvalidateFlags::Table | SwInvalidateFlags::Section;
921 lcl_InvalidateAllContent(*this, nInv);
922 }
923}
924
925void SwViewShell::SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys)
926{
927 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
928 rIDSA.set(DocumentSettingId::SUBTRACT_FLYS, bSubtractFlysAnchoredAtFlys);
929}
930
931void SwViewShell::SetEmptyDbFieldHidesPara(bool bEmptyDbFieldHidesPara)
932{
933 IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess();
934 if (rIDSA.get(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA) == bEmptyDbFieldHidesPara)
935 return;
936
937 SwWait aWait(*GetDoc()->GetDocShell(), true);
938 rIDSA.set(DocumentSettingId::EMPTY_DB_FIELD_HIDES_PARA, bEmptyDbFieldHidesPara);
939 StartAction();
940 GetDoc()->getIDocumentState().SetModified();
941 for (auto const & pFieldType : *GetDoc()->getIDocumentFieldsAccess().GetFieldTypes())
942 {
943 if (pFieldType->Which() == SwFieldIds::Database)
944 {
945 pFieldType->ModifyNotification(nullptr, nullptr);
946 }
947 }
948 EndAction();
949}
950
951void SwViewShell::Reformat()
952{
953 SwWait aWait( *GetDoc()->GetDocShell(), true );
954
955 // we go for safe: get rid of the old font information,
956 // when the printer resolution or zoom factor changes.
957 // Init() and Reformat() are the safest locations.
958 pFntCache->Flush( );
959
960 if( GetLayout()->IsCallbackActionEnabled() )
961 {
962 StartAction();
963 GetLayout()->InvalidateAllContent( SwInvalidateFlags::Size | SwInvalidateFlags::Pos | SwInvalidateFlags::PrtArea );
964 EndAction();
965 }
966}
967
968void SwViewShell::ChgNumberDigits()
969{
970 SdrModel* pTmpDrawModel = getIDocumentDrawModelAccess().GetDrawModel();
971 if ( pTmpDrawModel )
972 pTmpDrawModel->ReformatAllTextObjects();
973 Reformat();
974}
975
976void SwViewShell::CalcLayout()
977{
978 // extremely likely to be a Bad Idea to call this without StartAction
979 // (except the Page Preview apparently only has a non-subclassed ViewShell)
980 assert((typeid(*this) == typeid(SwViewShell)) || mnStartAction)(static_cast <bool> ((typeid(*this) == typeid(SwViewShell
)) || mnStartAction) ? void (0) : __assert_fail ("(typeid(*this) == typeid(SwViewShell)) || mnStartAction"
, "/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
, 980, __extension__ __PRETTY_FUNCTION__))
;
981
982 CurrShell aCurr( this );
983 SwWait aWait( *GetDoc()->GetDocShell(), true );
984
985 // Preserve top of the text frame cache.
986 SwSaveSetLRUOfst aSaveLRU;
987
988 //switch on Progress when none is running yet.
989 const bool bEndProgress = SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) == nullptr;
990 if ( bEndProgress )
991 {
992 long nEndPage = GetLayout()->GetPageNum();
993 nEndPage += nEndPage * 10 / 100;
994 ::StartProgress( STR_STATSTR_REFORMATreinterpret_cast<char const *>("STR_STATSTR_REFORMAT" "\004"
u8"Repagination...")
, 0, nEndPage, GetDoc()->GetDocShell() );
995 }
996
997 SwLayAction aAction( GetLayout(), Imp() );
998 aAction.SetPaint( false );
999 aAction.SetStatBar( true );
1000 aAction.SetCalcLayout( true );
1001 aAction.SetReschedule( true );
1002 GetDoc()->getIDocumentFieldsAccess().LockExpFields();
1003 aAction.Action(GetOut());
1004 GetDoc()->getIDocumentFieldsAccess().UnlockExpFields();
1005
1006 //the SetNewFieldLst() on the Doc was cut off and must be fetched again
1007 //(see flowfrm.cxx, txtfld.cxx)
1008 if ( aAction.IsExpFields() )
1009 {
1010 aAction.Reset();
1011 aAction.SetPaint( false );
1012 aAction.SetStatBar( true );
1013 aAction.SetReschedule( true );
1014
1015 SwDocPosUpdate aMsgHint( 0 );
1016 GetDoc()->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
1017 GetDoc()->getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
1018
1019 aAction.Action(GetOut());
1020 }
1021
1022 if ( VisArea().HasArea() )
1023 InvalidateWindows( VisArea() );
1024 if ( bEndProgress )
1025 ::EndProgress( GetDoc()->GetDocShell() );
1026}
1027
1028void SwViewShell::SetFirstVisPageInvalid()
1029{
1030 for(SwViewShell& rSh : GetRingContainer())
1031 {
1032 if ( rSh.Imp() )
1033 rSh.Imp()->SetFirstVisPageInvalid();
1034 }
1035}
1036
1037void SwViewShell::SizeChgNotify()
1038{
1039 if ( !mpWin )
1040 mbDocSizeChgd = true;
1041 else if( ActionPend() || Imp()->IsCalcLayoutProgress() || mbPaintInProgress )
1042 {
1043 mbDocSizeChgd = true;
1044
1045 if ( !Imp()->IsCalcLayoutProgress() && dynamic_cast<const SwCursorShell*>( this ) != nullptr )
1046 {
1047 const SwFrame *pCnt = static_cast<SwCursorShell*>(this)->GetCurrFrame( false );
1048 const SwPageFrame *pPage;
1049 if ( pCnt && nullptr != (pPage = pCnt->FindPageFrame()) )
1050 {
1051 const sal_uInt16 nVirtNum = pPage->GetVirtPageNum();
1052 const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
1053 OUString sDisplay = rNum.GetNumStr( nVirtNum );
1054 PageNumNotify( this, pCnt->GetPhyPageNum(), nVirtNum, sDisplay );
1055
1056 if (comphelper::LibreOfficeKit::isActive())
1057 {
1058 Size aDocSize = GetDocSize();
1059 std::stringstream ss;
1060 ss << aDocSize.Width() + 2 * DOCUMENTBORDER284 << ", " << aDocSize.Height() + 2 * DOCUMENTBORDER284;
1061 OString sSize = ss.str().c_str();
1062
1063 SwXTextDocument* pModel = comphelper::getUnoTunnelImplementation<SwXTextDocument>(GetSfxViewShell()->GetCurrentDocument());
1064 SfxLokHelper::notifyDocumentSizeChanged(GetSfxViewShell(), sSize, pModel);
1065 }
1066 }
1067 }
1068 }
1069 else
1070 {
1071 mbDocSizeChgd = false;
1072 ::SizeNotify( this, GetDocSize() );
1073 }
1074}
1075
1076void SwViewShell::VisPortChgd( const SwRect &rRect)
1077{
1078 OSL_ENSURE( GetWin(), "VisPortChgd without Window." )do { if (true && (!(GetWin()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "1078" ": "), "%s", "VisPortChgd without Window."); } } while
(false)
;
1079
1080 if ( rRect == VisArea() )
1081 return;
1082
1083 // Is someone spuriously rescheduling again?
1084 SAL_WARN_IF(mbInEndAction, "sw.core", "Scrolling during EndAction")do { if (true && (mbInEndAction)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "sw.core")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "Scrolling during EndAction"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"
), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "1084" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Scrolling during EndAction"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Scrolling during EndAction"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "1084" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Scrolling during EndAction") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "1084" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Scrolling during EndAction"), 0); }
else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Scrolling during EndAction"; ::sal::detail::log( (
::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.core"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "1084" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1085
1086 //First get the old visible page, so we don't have to look
1087 //for it afterwards.
1088 const SwFrame *pOldPage = Imp()->GetFirstVisPage(GetWin());
1089
1090 const SwRect aPrevArea( VisArea() );
1091 const bool bFull = aPrevArea.IsEmpty();
1092 maVisArea = rRect;
1093 SetFirstVisPageInvalid();
1094
1095 //When there a PaintRegion still exists and the VisArea has changed,
1096 //the PaintRegion is at least by now obsolete. The PaintRegion can
1097 //have been created by RootFrame::PaintSwFrame.
1098 if ( !mbInEndAction &&
1099 Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() )
1100 Imp()->DelRegion();
1101
1102 CurrShell aCurr( this );
1103
1104 bool bScrolled = false;
1105
1106 SwPostItMgr* pPostItMgr = GetPostItMgr();
1107
1108 if ( bFull )
1109 GetWin()->Invalidate();
1110 else
1111 {
1112 //Calculate amount to be scrolled.
1113 const long nXDiff = aPrevArea.Left() - VisArea().Left();
1114 const long nYDiff = aPrevArea.Top() - VisArea().Top();
1115
1116 if( !nXDiff && !GetViewOptions()->getBrowseMode() &&
1117 (!Imp()->HasDrawView() || !Imp()->GetDrawView()->IsGridVisible() ) )
1118 {
1119 // If possible, don't scroll the application background
1120 // (PaintDesktop). Also limit the left and right side of
1121 // the scroll range to the pages.
1122 const SwPageFrame *pPage = static_cast<SwPageFrame*>(GetLayout()->Lower());
1123 if ( pPage->getFrameArea().Top() > pOldPage->getFrameArea().Top() )
1124 pPage = static_cast<const SwPageFrame*>(pOldPage);
1125 SwRect aBoth( VisArea() );
1126 aBoth.Union( aPrevArea );
1127 const SwTwips nBottom = aBoth.Bottom();
1128 SwTwips nMinLeft = SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF);
1129 SwTwips nMaxRight= 0;
1130
1131 const bool bBookMode = GetViewOptions()->IsViewLayoutBookMode();
1132
1133 while ( pPage && pPage->getFrameArea().Top() <= nBottom )
1134 {
1135 SwRect aPageRect( pPage->GetBoundRect(GetWin()) );
1136 if ( bBookMode )
1137 {
1138 const SwPageFrame& rFormatPage = pPage->GetFormatPage();
1139 aPageRect.SSize( rFormatPage.GetBoundRect(GetWin()).SSize() );
1140 }
1141
1142 // #i9719# - consider new border and shadow width
1143 if ( aPageRect.IsOver( aBoth ) )
1144 {
1145 SwTwips nPageLeft = 0;
1146 SwTwips nPageRight = 0;
1147 const sw::sidebarwindows::SidebarPosition aSidebarPos = pPage->SidebarPosition();
1148
1149 if( aSidebarPos != sw::sidebarwindows::SidebarPosition::NONE )
1150 {
1151 nPageLeft = aPageRect.Left();
1152 nPageRight = aPageRect.Right();
1153 }
1154
1155 if( nPageLeft < nMinLeft )
1156 nMinLeft = nPageLeft;
1157 if( nPageRight > nMaxRight )
1158 nMaxRight = nPageRight;
1159 //match with the draw objects
1160 //take nOfst into account as the objects have been
1161 //selected and have handles attached.
1162 if ( pPage->GetSortedObjs() )
1163 {
1164 const long nOfst = GetOut()->PixelToLogic(
1165 Size(Imp()->GetDrawView()->GetMarkHdlSizePixel()/2,0)).Width();
1166 for (SwAnchoredObject* pObj : *pPage->GetSortedObjs())
1167 {
1168 // ignore objects that are not actually placed on the page
1169 if (pObj->IsFormatPossible())
1170 {
1171 const tools::Rectangle &rBound = pObj->GetObjRect().SVRect();
1172 if (rBound.Left() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000)) {
1173 // OD 03.03.2003 #107927# - use correct datatype
1174 const SwTwips nL = std::max( 0L, rBound.Left() - nOfst );
1175 if ( nL < nMinLeft )
1176 nMinLeft = nL;
1177 if( rBound.Right() + nOfst > nMaxRight )
1178 nMaxRight = rBound.Right() + nOfst;
1179 }
1180 }
1181 }
1182 }
1183 }
1184 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1185 }
1186 tools::Rectangle aRect( aPrevArea.SVRect() );
1187 aRect.SetLeft( nMinLeft );
1188 aRect.SetRight( nMaxRight );
1189 if( VisArea().IsOver( aPrevArea ) && !mnLockPaint )
1190 {
1191 bScrolled = true;
1192 maVisArea.Pos() = aPrevArea.Pos();
1193 if ( SmoothScroll( nXDiff, nYDiff, &aRect ) )
1194 return;
1195 maVisArea.Pos() = rRect.Pos();
1196 }
1197 else
1198 GetWin()->Invalidate( aRect );
1199 }
1200 else if ( !mnLockPaint ) //will be released in Unlock
1201 {
1202 if( VisArea().IsOver( aPrevArea ) )
1203 {
1204 bScrolled = true;
1205 maVisArea.Pos() = aPrevArea.Pos();
1206 if ( SmoothScroll( nXDiff, nYDiff, nullptr ) )
1207 return;
1208 maVisArea.Pos() = rRect.Pos();
1209 }
1210 else
1211 GetWin()->Invalidate();
1212 }
1213 }
1214
1215 // When tiled rendering, the map mode of the window is disabled, avoid
1216 // enabling it here.
1217 if (!comphelper::LibreOfficeKit::isActive())
1218 {
1219 Point aPt( VisArea().Pos() );
1220 aPt.setX( -aPt.X() ); aPt.setY( -aPt.Y() );
1221 MapMode aMapMode( GetWin()->GetMapMode() );
1222 aMapMode.SetOrigin( aPt );
1223 GetWin()->SetMapMode( aMapMode );
1224 }
1225
1226 if ( HasDrawView() )
1227 {
1228 Imp()->GetDrawView()->VisAreaChanged( GetWin() );
1229 Imp()->GetDrawView()->SetActualWin( GetWin() );
1230 }
1231 GetWin()->PaintImmediately();
1232
1233 if ( pPostItMgr ) // #i88070#
1234 {
1235 pPostItMgr->Rescale();
1236 pPostItMgr->CalcRects();
1237 pPostItMgr->LayoutPostIts();
1238 }
1239
1240 if ( !bScrolled && pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1241 pPostItMgr->CorrectPositions();
1242
1243 if( Imp()->IsAccessible() )
1244 Imp()->UpdateAccessible();
1245}
1246
1247bool SwViewShell::SmoothScroll( long lXDiff, long lYDiff, const tools::Rectangle *pRect )
1248{
1249#if !defined(MACOSX) && !defined(ANDROID) && !defined(IOS)
1250 // #i98766# - disable smooth scrolling for Mac
1251
1252 const sal_uLong nBitCnt = mpOut->GetBitCount();
1253 long lMult = 1, lMax = LONG_MAX9223372036854775807L;
1254 if ( nBitCnt == 16 )
1255 {
1256 lMax = 7000;
1257 lMult = 2;
1258 }
1259 if ( nBitCnt == 24 )
1260 {
1261 lMax = 5000;
1262 lMult = 6;
1263 }
1264 else if ( nBitCnt == 1 )
1265 {
1266 lMax = 3000;
1267 lMult = 12;
1268 }
1269
1270 // #i75172# isolated static conditions
1271 const bool bOnlyYScroll(!lXDiff && std::abs(lYDiff) != 0 && std::abs(lYDiff) < lMax);
1272 const bool bAllowedWithChildWindows(GetWin()->GetWindowClipRegionPixel().IsNull());
1273 const bool bSmoothScrollAllowed(bOnlyYScroll && mbEnableSmooth && GetViewOptions()->IsSmoothScroll() && bAllowedWithChildWindows);
1274
1275 if(bSmoothScrollAllowed)
1276 {
1277 Imp()->m_bStopSmooth = false;
1278
1279 const SwRect aOldVis( VisArea() );
1280
1281 //create virtual device and set.
1282 const Size aPixSz = GetWin()->PixelToLogic(Size(1,1));
1283 VclPtrInstance<VirtualDevice> pVout( *GetWin() );
1284 pVout->SetLineColor( GetWin()->GetLineColor() );
1285 pVout->SetFillColor( GetWin()->GetFillColor() );
1286 MapMode aMapMode( GetWin()->GetMapMode() );
1287 pVout->SetMapMode( aMapMode );
1288 Size aSize( maVisArea.Width()+2*aPixSz.Width(), std::abs(lYDiff)+(2*aPixSz.Height()) );
1289 if ( pRect )
1290 aSize.setWidth( std::min(aSize.Width(), pRect->GetWidth()+2*aPixSz.Width()) );
1291 if ( pVout->SetOutputSize( aSize ) )
1292 {
1293 mnLockPaint++;
1294
1295 //First Paint everything in the virtual device.
1296 SwRect aRect( VisArea() );
1297 aRect.Height( aSize.Height() );
1298 if ( pRect )
1299 {
1300 aRect.Pos().setX( std::max(aRect.Left(),pRect->Left()-aPixSz.Width()) );
1301 aRect.Right( std::min(aRect.Right()+2*aPixSz.Width(), pRect->Right()+aPixSz.Width()));
1302 }
1303 else
1304 aRect.AddWidth(2*aPixSz.Width() );
1305 aRect.Pos().setY( lYDiff < 0 ? aOldVis.Bottom() - aPixSz.Height()
1306 : aRect.Top() - aSize.Height() + aPixSz.Height() );
1307 aRect.Pos().setX( std::max( 0L, aRect.Left()-aPixSz.Width() ) );
1308 aRect.Pos() = GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.Pos()));
1309 aRect.SSize( GetWin()->PixelToLogic( GetWin()->LogicToPixel( aRect.SSize())) );
1310 maVisArea = aRect;
1311 const Point aPt( -aRect.Left(), -aRect.Top() );
1312 aMapMode.SetOrigin( aPt );
1313 pVout->SetMapMode( aMapMode );
1314 OutputDevice *pOld = mpOut;
1315 mpOut = pVout.get();
1316
1317 {
1318 // #i75172# To get a clean repaint, a new ObjectContact is needed here. Without, the
1319 // repaint would not be correct since it would use the wrong DrawPage visible region.
1320 // This repaint IS about painting something currently outside the visible part (!).
1321 // For that purpose, AddWindowToPaintView is used which creates a new SdrPageViewWindow
1322 // and all the necessary stuff. It's not cheap, but necessary here. Alone because repaint
1323 // target really is NOT the current window.
1324 // Also will automatically NOT use PreRendering and overlay (since target is VirtualDevice)
1325 if(!HasDrawView())
1326 MakeDrawView();
1327 SdrView* pDrawView = GetDrawView();
1328 pDrawView->AddWindowToPaintView(pVout, nullptr);
1329
1330 // clear mpWin during DLPrePaint2 to get paint preparation for mpOut, but set it again
1331 // immediately afterwards. There are many decisions in SW which imply that Printing
1332 // is used when mpWin == 0 (wrong but widely used).
1333 vcl::Window* pOldWin = mpWin;
1334 mpWin = nullptr;
1335 DLPrePaint2(vcl::Region(aRect.SVRect()));
1336 mpWin = pOldWin;
1337
1338 // SW paint stuff
1339 PaintDesktop(*GetOut(), aRect);
1340 SwViewShell::mbLstAct = true;
1341 GetLayout()->PaintSwFrame( *GetOut(), aRect );
1342 SwViewShell::mbLstAct = false;
1343
1344 // end paint and destroy ObjectContact again
1345 DLPostPaint2(true);
1346 pDrawView->DeleteWindowFromPaintView(pVout);
1347 }
1348
1349 mpOut = pOld;
1350 maVisArea = aOldVis;
1351
1352 //Now shift in parts and copy the new Pixel from the virtual device.
1353
1354 // ??????????????????????
1355 // or is it better to get the scrollfactor from the User
1356 // as option?
1357 // ??????????????????????
1358 long lMaDelta = aPixSz.Height();
1359 if ( std::abs(lYDiff) > ( maVisArea.Height() / 3 ) )
1360 lMaDelta *= 6;
1361 else
1362 lMaDelta *= 2;
1363
1364 lMaDelta *= lMult;
1365
1366 if ( lYDiff < 0 )
1367 lMaDelta = -lMaDelta;
1368
1369 long lDiff = lYDiff;
1370 while ( lDiff )
1371 {
1372 long lScroll;
1373 if ( Imp()->m_bStopSmooth || std::abs(lDiff) <= std::abs(lMaDelta) )
1374 {
1375 lScroll = lDiff;
1376 lDiff = 0;
1377 }
1378 else
1379 {
1380 lScroll = lMaDelta;
1381 lDiff -= lMaDelta;
1382 }
1383
1384 const SwRect aTmpOldVis = VisArea();
1385 maVisArea.Pos().AdjustY( -lScroll );
1386 maVisArea.Pos() = GetWin()->PixelToLogic( GetWin()->LogicToPixel( VisArea().Pos()));
1387 lScroll = aTmpOldVis.Top() - VisArea().Top();
1388 if ( pRect )
1389 {
1390 tools::Rectangle aTmp( aTmpOldVis.SVRect() );
1391 aTmp.SetLeft( pRect->Left() );
1392 aTmp.SetRight( pRect->Right() );
1393 GetWin()->Scroll( 0, lScroll, aTmp, ScrollFlags::Children);
1394 }
1395 else
1396 GetWin()->Scroll( 0, lScroll, ScrollFlags::Children );
1397
1398 const Point aTmpPt( -VisArea().Left(), -VisArea().Top() );
1399 MapMode aTmpMapMode( GetWin()->GetMapMode() );
1400 aTmpMapMode.SetOrigin( aTmpPt );
1401 GetWin()->SetMapMode( aTmpMapMode );
1402
1403 if ( Imp()->HasDrawView() )
1404 Imp()->GetDrawView()->VisAreaChanged( GetWin() );
1405
1406 SetFirstVisPageInvalid();
1407 if ( !Imp()->m_bStopSmooth )
1408 {
1409 const bool bScrollDirectionIsUp(lScroll > 0);
1410 Imp()->m_aSmoothRect = VisArea();
1411
1412 if(bScrollDirectionIsUp)
1413 {
1414 Imp()->m_aSmoothRect.Bottom( VisArea().Top() + lScroll + aPixSz.Height());
1415 }
1416 else
1417 {
1418 Imp()->m_aSmoothRect.Top( VisArea().Bottom() + lScroll - aPixSz.Height());
1419 }
1420
1421 Imp()->m_bSmoothUpdate = true;
1422 GetWin()->PaintImmediately();
1423 Imp()->m_bSmoothUpdate = false;
1424
1425 if(!Imp()->m_bStopSmooth)
1426 {
1427 // start paint on logic base
1428 const tools::Rectangle aTargetLogic(Imp()->m_aSmoothRect.SVRect());
1429 DLPrePaint2(vcl::Region(aTargetLogic));
1430
1431 // get target rectangle in discrete pixels
1432 OutputDevice& rTargetDevice = mpTargetPaintWindow->GetTargetOutputDevice();
1433 const tools::Rectangle aTargetPixel(rTargetDevice.LogicToPixel(aTargetLogic));
1434
1435 // get source top-left in discrete pixels
1436 const Point aSourceTopLeft(pVout->LogicToPixel(aTargetLogic.TopLeft()));
1437
1438 // switch off MapModes
1439 const bool bMapModeWasEnabledDest(rTargetDevice.IsMapModeEnabled());
1440 const bool bMapModeWasEnabledSource(pVout->IsMapModeEnabled());
1441 rTargetDevice.EnableMapMode(false);
1442 pVout->EnableMapMode(false);
1443
1444 rTargetDevice.DrawOutDev(
1445 aTargetPixel.TopLeft(), aTargetPixel.GetSize(), // dest
1446 aSourceTopLeft, aTargetPixel.GetSize(), // source
1447 *pVout);
1448
1449 // restore MapModes
1450 rTargetDevice.EnableMapMode(bMapModeWasEnabledDest);
1451 pVout->EnableMapMode(bMapModeWasEnabledSource);
1452
1453 // end paint on logoc base
1454 DLPostPaint2(true);
1455 }
1456 else
1457 --mnLockPaint;
1458 }
1459 }
1460 pVout.disposeAndClear();
1461 GetWin()->PaintImmediately();
1462 if ( !Imp()->m_bStopSmooth )
1463 --mnLockPaint;
1464 SetFirstVisPageInvalid();
1465 return true;
1466 }
1467 pVout.disposeAndClear();
1468 }
1469#endif
1470
1471 maVisArea.Pos().AdjustX( -lXDiff );
1472 maVisArea.Pos().AdjustY( -lYDiff );
1473 if ( pRect )
1474 GetWin()->Scroll( lXDiff, lYDiff, *pRect, ScrollFlags::Children);
1475 else
1476 GetWin()->Scroll( lXDiff, lYDiff, ScrollFlags::Children);
1477 return false;
1478}
1479
1480void SwViewShell::PaintDesktop(vcl::RenderContext& rRenderContext, const SwRect &rRect)
1481{
1482 if ( !GetWin() && !GetOut()->GetConnectMetaFile() )
1483 return; //for the printer we don't do anything here.
1484
1485 //Catch exceptions, so that it doesn't look so surprising.
1486 //Can e.g. happen during Idle.
1487 //Unfortunately we must at any rate Paint the rectangles next to the pages,
1488 //as these are not painted at VisPortChgd.
1489 bool bBorderOnly = false;
1490 const SwRootFrame *pRoot = GetLayout();
1491 if ( rRect.Top() > pRoot->getFrameArea().Bottom() )
1492 {
1493 const SwFrame *pPg = pRoot->Lower();
1494 while ( pPg && pPg->GetNext() )
1495 pPg = pPg->GetNext();
1496 if ( !pPg || !pPg->getFrameArea().IsOver( VisArea() ) )
1497 bBorderOnly = true;
1498 }
1499
1500 const bool bBookMode = GetViewOptions()->IsViewLayoutBookMode();
1501
1502 SwRegionRects aRegion( rRect );
1503
1504 //mod #i6193: remove sidebar area to avoid flickering
1505 const SwPostItMgr* pPostItMgr = GetPostItMgr();
1506 const SwTwips nSidebarWidth = pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ?
1507 pPostItMgr->GetSidebarWidth() + pPostItMgr->GetSidebarBorderWidth() :
1508 0;
1509
1510 if ( bBorderOnly )
1511 {
1512 const SwFrame *pPage =pRoot->Lower();
1513 SwRect aLeft( rRect ), aRight( rRect );
1514 while ( pPage )
1515 {
1516 long nTmp = pPage->getFrameArea().Left();
1517 if ( nTmp < aLeft.Right() )
1518 aLeft.Right( nTmp );
1519 nTmp = pPage->getFrameArea().Right();
1520 if ( nTmp > aRight.Left() )
1521 {
1522 aRight.Left( nTmp + nSidebarWidth );
1523 }
1524 pPage = pPage->GetNext();
1525 }
1526 aRegion.clear();
1527 if ( aLeft.HasArea() )
1528 aRegion.push_back( aLeft );
1529 if ( aRight.HasArea() )
1530 aRegion.push_back( aRight );
1531 }
1532 else
1533 {
1534 const SwFrame *pPage = Imp()->GetFirstVisPage(&rRenderContext);
1535 const SwTwips nBottom = rRect.Bottom();
1536 while ( pPage && !aRegion.empty() &&
1537 (pPage->getFrameArea().Top() <= nBottom) )
1538 {
1539 SwRect aPageRect( pPage->getFrameArea() );
1540 if ( bBookMode )
1541 {
1542 const SwPageFrame& rFormatPage = static_cast<const SwPageFrame*>(pPage)->GetFormatPage();
1543 aPageRect.SSize( rFormatPage.getFrameArea().SSize() );
1544 }
1545
1546 const bool bSidebarRight =
1547 static_cast<const SwPageFrame*>(pPage)->SidebarPosition() == sw::sidebarwindows::SidebarPosition::RIGHT;
1548 aPageRect.Pos().AdjustX( -(bSidebarRight ? 0 : nSidebarWidth) );
1549 aPageRect.AddWidth(nSidebarWidth );
1550
1551 if ( aPageRect.IsOver( rRect ) )
1552 aRegion -= aPageRect;
1553
1554 pPage = pPage->GetNext();
1555 }
1556 }
1557 if ( !aRegion.empty() )
1558 PaintDesktop_(aRegion);
1559}
1560
1561// PaintDesktop is split in two, this part is also used by PreviewPage
1562void SwViewShell::PaintDesktop_(const SwRegionRects &rRegion)
1563{
1564 // OD 2004-04-23 #116347#
1565 GetOut()->Push( PushFlags::FILLCOLOR|PushFlags::LINECOLOR );
1566 GetOut()->SetLineColor();
1567
1568 for ( auto &rRgn : rRegion )
1569 {
1570 const tools::Rectangle aRectangle(rRgn.SVRect());
1571
1572 // #i93170#
1573 // Here we have a real Problem. On the one hand we have the buffering for paint
1574 // and overlay which needs an embracing pair of DLPrePaint2/DLPostPaint2 calls,
1575 // on the other hand the MapMode is not set correctly when this code is executed.
1576 // This is done in the users of this method, for each SWpage before painting it.
1577 // Since the MapMode is not correct here, the call to DLPostPaint2 will paint
1578 // existing FormControls due to the current MapMode.
1579
1580 // There are basically three solutions for this:
1581
1582 // (1) Set the MapMode correct, move the background painting to the users of
1583 // this code
1584
1585 // (2) Do no DLPrePaint2/DLPostPaint2 here; no SdrObjects are allowed to lie in
1586 // the desktop region. Disadvantage: the desktop will not be part of the
1587 // buffers, e.g. overlay. Thus, as soon as overlay will be used over the
1588 // desktop, it will not work.
1589
1590 // (3) expand DLPostPaint2 with a flag to signal if FormControl paints shall
1591 // be done or not
1592
1593 // Currently, (3) will be the best possible solution. It will keep overlay and
1594 // buffering intact and work without MapMode for single pages. In the medium
1595 // to long run, (1) will need to be used and the bool bPaintFormLayer needs
1596 // to be removed again
1597
1598 // #i68597# inform Drawinglayer about display change
1599 DLPrePaint2(vcl::Region(aRectangle));
1600
1601 // #i75172# needed to move line/Fill color setters into loop since DLPrePaint2
1602 // may exchange GetOut(), that's it's purpose. This happens e.g. at print preview.
1603 GetOut()->SetFillColor( SwViewOption::GetAppBackgroundColor());
1604 GetOut()->SetLineColor();
1605 GetOut()->DrawRect(aRectangle);
1606
1607 DLPostPaint2(false);
1608 }
1609
1610 GetOut()->Pop();
1611}
1612
1613bool SwViewShell::CheckInvalidForPaint( const SwRect &rRect )
1614{
1615 if ( !GetWin() )
1616 return false;
1617
1618 const SwPageFrame *pPage = Imp()->GetFirstVisPage(GetOut());
1619 const SwTwips nBottom = VisArea().Bottom();
1620 const SwTwips nRight = VisArea().Right();
1621 bool bRet = false;
1622 while ( !bRet && pPage && ((pPage->getFrameArea().Top() <= nBottom) &&
1623 (pPage->getFrameArea().Left() <= nRight)))
1624 {
1625 if ( pPage->IsInvalid() || pPage->IsInvalidFly() )
1626 bRet = true;
1627 pPage = static_cast<const SwPageFrame*>(pPage->GetNext());
1628 }
1629
1630 if ( bRet )
1631 {
1632 //Unfortunately Start/EndAction won't help here, as the Paint originated
1633 //from GUI and so Clipping has been set against getting through.
1634 //Ergo: do it all yourself (see ImplEndAction())
1635 if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea())
1636 Imp()->DelRegion();
1637
1638 SwLayAction aAction( GetLayout(), Imp() );
1639 aAction.SetComplete( false );
1640 // We increment the action counter to avoid a recursive call of actions
1641 // e.g. from a SwFEShell::RequestObjectResize(..) in bug 95829.
1642 // A recursive call of actions is no good idea because the inner action
1643 // can't format frames which are locked by the outer action. This may
1644 // cause and endless loop.
1645 ++mnStartAction;
1646 aAction.Action(GetWin());
1647 --mnStartAction;
1648
1649 SwRegionRects *pRegion = Imp()->GetRegion();
1650 if ( pRegion && aAction.IsBrowseActionStop() )
1651 {
1652 //only of interest when something has changed in the visible range
1653 bool bStop = true;
1654 for ( size_t i = 0; i < pRegion->size(); ++i )
1655 {
1656 const SwRect &rTmp = (*pRegion)[i];
1657 bStop = rTmp.IsOver( VisArea() );
1658 if ( !bStop )
1659 break;
1660 }
1661 if ( bStop )
1662 {
1663 Imp()->DelRegion();
1664 pRegion = nullptr;
1665 }
1666 }
1667
1668 if ( pRegion )
1669 {
1670 //First Invert then Compress, never the other way round!
1671 pRegion->Invert();
1672 pRegion->Compress();
1673 bRet = false;
1674 if ( !pRegion->empty() )
1675 {
1676 SwRegionRects aRegion( rRect );
1677 for ( size_t i = 0; i < pRegion->size(); ++i )
1678 { const SwRect &rTmp = (*pRegion)[i];
1679 if ( !rRect.IsInside( rTmp ) )
1680 {
1681 InvalidateWindows( rTmp );
1682 if ( rTmp.IsOver( VisArea() ) )
1683 { aRegion -= rTmp;
1684 bRet = true;
1685 }
1686 }
1687 }
1688 if ( bRet )
1689 {
1690 for ( size_t i = 0; i < aRegion.size(); ++i )
1691 GetWin()->Invalidate( aRegion[i].SVRect() );
1692
1693 if ( rRect != VisArea() )
1694 {
1695 //rRect == VisArea is the special case for new or
1696 //Shift-Ctrl-R, when it shouldn't be necessary to
1697 //hold the rRect again in Document coordinates.
1698 if ( maInvalidRect.IsEmpty() )
1699 maInvalidRect = rRect;
1700 else
1701 maInvalidRect.Union( rRect );
1702 }
1703 }
1704 }
1705 else
1706 bRet = false;
1707 Imp()->DelRegion();
1708 }
1709 else
1710 bRet = false;
1711 }
1712 return bRet;
1713}
1714
1715namespace
1716{
1717/// Similar to comphelper::FlagRestorationGuard, but for vcl::RenderContext.
1718class RenderContextGuard
1719{
1720 std::unique_ptr<SdrPaintWindow> m_TemporaryPaintWindow;
1721 SdrPageWindow* m_pPatchedPageWindow;
1722 SdrPaintWindow* m_pPreviousPaintWindow = nullptr;
1723
1724public:
1725 RenderContextGuard(VclPtr<vcl::RenderContext>& pRef, vcl::RenderContext* pValue, SwViewShell* pShell)
1726 : m_pPatchedPageWindow(nullptr)
1727 {
1728 pRef = pValue;
1729
1730 if (pValue == pShell->GetWin())
1731 return;
1732
1733 SdrView* pDrawView(pShell->Imp()->GetDrawView());
1734
1735 if (nullptr == pDrawView)
1736 return;
1737
1738 SdrPageView* pSdrPageView(pDrawView->GetSdrPageView());
1739
1740 if (nullptr != pSdrPageView)
1741 {
1742 m_pPatchedPageWindow = pSdrPageView->FindPageWindow(*pShell->GetWin());
1743
1744 if (nullptr != m_pPatchedPageWindow)
1745 {
1746 m_TemporaryPaintWindow.reset(new SdrPaintWindow(*pDrawView, *pValue));
1747 m_pPreviousPaintWindow = m_pPatchedPageWindow->patchPaintWindow(*m_TemporaryPaintWindow);
1748 }
1749 }
1750 }
1751
1752 ~RenderContextGuard()
1753 {
1754 if(nullptr != m_pPatchedPageWindow)
1755 {
1756 m_pPatchedPageWindow->unpatchPaintWindow(m_pPreviousPaintWindow);
1757 }
1758 }
1759};
1760}
1761
1762void SwViewShell::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect)
1763{
1764 RenderContextGuard aGuard(mpOut, &rRenderContext, this);
1765 if ( mnLockPaint )
1766 {
1767 if ( Imp()->m_bSmoothUpdate )
1768 {
1769 SwRect aTmp( rRect );
1770 if ( !Imp()->m_aSmoothRect.IsInside( aTmp ) )
1771 Imp()->m_bStopSmooth = true;
1772 else
1773 {
1774 Imp()->m_aSmoothRect = aTmp;
1775 return;
1776 }
1777 }
1778 else
1779 return;
1780 }
1781
1782 if ( SwRootFrame::IsInPaint() )
1783 {
1784 //During the publication of a page at printing the Paint is buffered.
1785 SwPaintQueue::Add( this, SwRect( rRect ) );
1786 return;
1787 }
1788
1789 //With !nStartAction I try to protect me against erroneous code at other places.
1790 //Hopefully it will not lead to problems!?
1791 if ( mbPaintWorks && !mnStartAction )
1792 {
1793 if( GetWin() && GetWin()->IsVisible() )
1794 {
1795 SwRect aRect( rRect );
1796 if ( mbPaintInProgress ) //Guard against double Paints!
1797 {
1798 GetWin()->Invalidate( rRect );
1799 return;
1800 }
1801
1802 mbPaintInProgress = true;
1803 CurrShell aCurr( this );
1804 SwRootFrame::SetNoVirDev( true );
1805
1806 //We don't want to Clip to and from, we trust that all are limited
1807 //to the rectangle and only need to calculate the clipping once.
1808 //The ClipRect is removed here once and not recovered, as externally
1809 //no one needs it anymore anyway.
1810 //Not when we paint a Metafile.
1811 if( !GetOut()->GetConnectMetaFile() && GetOut()->IsClipRegion())
1812 GetOut()->SetClipRegion();
1813
1814 if ( IsPreview() )
1815 {
1816 //When useful, process or destroy the old InvalidRect.
1817 if ( aRect.IsInside( maInvalidRect ) )
1818 ResetInvalidRect();
1819 SwViewShell::mbLstAct = true;
1820 GetLayout()->PaintSwFrame( rRenderContext, aRect );
1821 SwViewShell::mbLstAct = false;
1822 }
1823 else
1824 {
1825 //When one of the visible pages still has anything entered for
1826 //Repaint, Repaint must be triggered.
1827 if ( !CheckInvalidForPaint( aRect ) )
1828 {
1829 // --> OD 2009-08-12 #i101192#
1830 // start Pre/PostPaint encapsulation to avoid screen blinking
1831 const vcl::Region aRepaintRegion(aRect.SVRect());
1832 DLPrePaint2(aRepaintRegion);
1833
1834 // <--
1835 PaintDesktop(rRenderContext, aRect);
1836
1837 //When useful, process or destroy the old InvalidRect.
1838 if ( aRect.IsInside( maInvalidRect ) )
1839 ResetInvalidRect();
1840 SwViewShell::mbLstAct = true;
1841 GetLayout()->PaintSwFrame( rRenderContext, aRect );
1842 SwViewShell::mbLstAct = false;
1843 // --> OD 2009-08-12 #i101192#
1844 // end Pre/PostPaint encapsulation
1845 DLPostPaint2(true);
1846 // <--
1847 }
1848 }
1849 SwRootFrame::SetNoVirDev( false );
1850 mbPaintInProgress = false;
1851 UISizeNotify();
1852 }
1853 }
1854 else
1855 {
1856 if ( maInvalidRect.IsEmpty() )
1857 maInvalidRect = SwRect( rRect );
1858 else
1859 maInvalidRect.Union( SwRect( rRect ) );
1860
1861 if ( mbInEndAction && GetWin() )
1862 {
1863 const vcl::Region aRegion(GetWin()->GetPaintRegion());
1864 RectangleVector aRectangles;
1865 aRegion.GetRegionRectangles(aRectangles);
1866
1867 for(const auto& rRectangle : aRectangles)
1868 {
1869 Imp()->AddPaintRect(rRectangle);
1870 }
1871
1872 //RegionHandle hHdl( aRegion.BeginEnumRects() );
1873 //Rectangle aRect;
1874 //while ( aRegion.GetEnumRects( hHdl, aRect ) )
1875 // Imp()->AddPaintRect( aRect );
1876 //aRegion.EndEnumRects( hHdl );
1877 }
1878 else if ( SfxProgress::GetActiveProgress( GetDoc()->GetDocShell() ) &&
1879 GetOut() == GetWin() )
1880 {
1881 // #i68597#
1882 const vcl::Region aDLRegion(rRect);
1883 DLPrePaint2(aDLRegion);
1884
1885 rRenderContext.Push( PushFlags::FILLCOLOR|PushFlags::LINECOLOR );
1886 rRenderContext.SetFillColor( Imp()->GetRetoucheColor() );
1887 rRenderContext.SetLineColor();
1888 rRenderContext.DrawRect( rRect );
1889 rRenderContext.Pop();
1890 // #i68597#
1891 DLPostPaint2(true);
1892 }
1893 }
1894}
1895
1896void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contextHeight, int tilePosX, int tilePosY, long tileWidth, long tileHeight)
1897{
1898 // SwViewShell's output device setup
1899 // TODO clean up SwViewShell's approach to output devices (the many of
1900 // them - mpBufferedOut, mpOut, mpWin, ...)
1901 OutputDevice *pSaveOut = mpOut;
1902 comphelper::LibreOfficeKit::setTiledPainting(true);
1903 mpOut = &rDevice;
1904
1905 // resizes the virtual device so to contain the entries context
1906 rDevice.SetOutputSizePixel(Size(contextWidth, contextHeight));
1907
1908 // setup the output device to draw the tile
1909 MapMode aMapMode(rDevice.GetMapMode());
1910 aMapMode.SetMapUnit(MapUnit::MapTwip);
1911 aMapMode.SetOrigin(Point(-tilePosX, -tilePosY));
1912
1913 // Scaling. Must convert from pixels to twips. We know
1914 // that VirtualDevices use a DPI of 96.
1915 Fraction scaleX = Fraction(contextWidth, 96) * Fraction(1440) / Fraction(tileWidth);
1916 Fraction scaleY = Fraction(contextHeight, 96) * Fraction(1440) / Fraction(tileHeight);
1917 aMapMode.SetScaleX(scaleX);
1918 aMapMode.SetScaleY(scaleY);
1919 rDevice.SetMapMode(aMapMode);
1920
1921 // Update scaling of SwEditWin and its sub-widgets, needed for comments.
1922 sal_uInt16 nOldZoomValue = 0;
1923 if (GetWin() && GetWin()->GetMapMode().GetScaleX() != scaleX)
1924 {
1925 double fScale = double(scaleX);
1926 SwViewOption aOption(*GetViewOptions());
1927 nOldZoomValue = aOption.GetZoom();
1928 aOption.SetZoom(fScale * 100);
1929 ApplyViewOptions(aOption);
1930 // Make sure the map mode (disabled in SwXTextDocument::initializeForTiledRendering()) is still disabled.
1931 GetWin()->EnableMapMode(false);
1932 }
1933
1934 tools::Rectangle aOutRect(Point(tilePosX, tilePosY),
1935 rDevice.PixelToLogic(Size(contextWidth, contextHeight)));
1936
1937 // Make the requested area visible -- we can't use MakeVisible as that will
1938 // only scroll the contents, but won't zoom/resize if needed.
1939 // Without this, items/text that are outside the visible area (in the SwView)
1940 // won't be painted when rendering tiles (at least when using either the
1941 // tiledrendering app, or the gtktiledviewer) -- although ultimately we
1942 // probably want to fix things so that the SwView's area doesn't affect
1943 // tiled rendering?
1944 VisPortChgd(SwRect(aOutRect));
1945
1946 // Invoke SwLayAction if layout is not yet ready.
1947 CheckInvalidForPaint(aOutRect);
1948
1949 // draw - works in logic coordinates
1950 Paint(rDevice, aOutRect);
1951
1952 SwPostItMgr* pPostItMgr = GetPostItMgr();
1953 if (GetViewOptions()->IsPostIts() && pPostItMgr)
1954 pPostItMgr->PaintTile(rDevice);
1955
1956 // SwViewShell's output device tear down
1957
1958 // A view shell can get a PaintTile call for a tile at a zoom level
1959 // different from the one, the related client really is.
1960 // In such a case it is better to reset the current scale value to
1961 // the original one, since such a value should be in synchronous with
1962 // the zoom level in the client (see setClientZoom).
1963 // At present the zoom value returned by GetViewOptions()->GetZoom() is
1964 // used in SwXTextDocument methods (postMouseEvent and setGraphicSelection)
1965 // for passing the correct mouse position to an edited chart (if any).
1966 if (nOldZoomValue !=0)
1967 {
1968 SwViewOption aOption(*GetViewOptions());
1969 aOption.SetZoom(nOldZoomValue);
1970 ApplyViewOptions(aOption);
1971
1972 // Changing the zoom value doesn't always trigger the updating of
1973 // the client ole object area, so we call it directly.
1974 SfxInPlaceClient* pIPClient = GetSfxViewShell()->GetIPClient();
1975 if (pIPClient)
1976 {
1977 pIPClient->VisAreaChanged();
1978 }
1979 // Make sure the map mode (disabled in SwXTextDocument::initializeForTiledRendering()) is still disabled.
1980 GetWin()->EnableMapMode(false);
1981 }
1982
1983 mpOut = pSaveOut;
1984 comphelper::LibreOfficeKit::setTiledPainting(false);
1985}
1986
1987void SwViewShell::SetBrowseBorder( const Size& rNew )
1988{
1989 if( rNew != maBrowseBorder )
1990 {
1991 maBrowseBorder = rNew;
1992 if ( maVisArea.HasArea() )
1993 InvalidateLayout( false );
1994 }
1995}
1996
1997const Size& SwViewShell::GetBrowseBorder() const
1998{
1999 return maBrowseBorder;
2000}
2001
2002sal_Int32 SwViewShell::GetBrowseWidth() const
2003{
2004 const SwPostItMgr* pPostItMgr = GetPostItMgr();
2005 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
2006 {
2007 Size aBorder( maBrowseBorder );
2008 aBorder.AdjustWidth(maBrowseBorder.Width() );
2009 aBorder.AdjustWidth(pPostItMgr->GetSidebarWidth(true) + pPostItMgr->GetSidebarBorderWidth(true) );
2010 return maVisArea.Width() - GetOut()->PixelToLogic(aBorder).Width();
2011 }
2012 else
2013 return maVisArea.Width() - 2 * GetOut()->PixelToLogic(maBrowseBorder).Width();
2014}
2015
2016void SwViewShell::InvalidateLayout( bool bSizeChanged )
2017{
2018 if ( !bSizeChanged && !GetViewOptions()->getBrowseMode() &&
2019 !GetViewOptions()->IsWhitespaceHidden() )
2020 return;
2021
2022 CurrShell aCurr( this );
2023
2024 OSL_ENSURE( GetLayout(), "Layout not ready" )do { if (true && (!(GetLayout()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2024" ": "), "%s", "Layout not ready"); } } while (false
)
;
2025
2026 // When the Layout doesn't have a height yet, nothing is formatted.
2027 // That leads to problems with Invalidate, e.g. when setting up a new View
2028 // the content is inserted and formatted (regardless of empty VisArea).
2029 // Therefore the pages must be roused for formatting.
2030 if( !GetLayout()->getFrameArea().Height() )
2031 {
2032 SwFrame* pPage = GetLayout()->Lower();
2033 while( pPage )
2034 {
2035 pPage->InvalidateSize_();
2036 pPage = pPage->GetNext();
2037 }
2038 return;
2039 }
2040
2041 LockPaint();
2042 StartAction();
2043
2044 SwPageFrame *pPg = static_cast<SwPageFrame*>(GetLayout()->Lower());
2045 do
2046 { pPg->InvalidateSize();
2047 pPg->InvalidatePrt_();
2048 pPg->InvaPercentLowers();
2049 if ( bSizeChanged )
2050 {
2051 pPg->PrepareHeader();
2052 pPg->PrepareFooter();
2053 }
2054 pPg = static_cast<SwPageFrame*>(pPg->GetNext());
2055 } while ( pPg );
2056
2057 // When the size ratios in browse mode change,
2058 // the Position and PrtArea of the Content and Tab frames must be Invalidated.
2059 SwInvalidateFlags nInv = SwInvalidateFlags::PrtArea | SwInvalidateFlags::Table | SwInvalidateFlags::Pos;
2060 // In case of layout or mode change, the ContentFrames need a size-Invalidate
2061 // because of printer/screen formatting.
2062 if ( bSizeChanged )
2063 nInv |= SwInvalidateFlags::Size | SwInvalidateFlags::Direction;
2064
2065 GetLayout()->InvalidateAllContent( nInv );
2066
2067 SwFrame::CheckPageDescs( static_cast<SwPageFrame*>(GetLayout()->Lower()) );
2068
2069 EndAction();
2070 UnlockPaint();
2071}
2072
2073SwRootFrame *SwViewShell::GetLayout() const
2074{
2075 return mpLayout.get();
2076}
2077
2078vcl::RenderContext& SwViewShell::GetRefDev() const
2079{
2080 OutputDevice* pTmpOut = nullptr;
2081 if ( GetWin() &&
2082 GetViewOptions()->getBrowseMode() &&
2083 !GetViewOptions()->IsPrtFormat() )
2084 pTmpOut = GetWin();
2085 else
2086 pTmpOut = GetDoc()->getIDocumentDeviceAccess().getReferenceDevice( true );
2087
2088 return *pTmpOut;
2089}
2090
2091const SwNodes& SwViewShell::GetNodes() const
2092{
2093 return mxDoc->GetNodes();
2094}
2095
2096void SwViewShell::DrawSelChanged()
2097{
2098}
2099
2100Size SwViewShell::GetDocSize() const
2101{
2102 Size aSz;
2103 const SwRootFrame* pRoot = GetLayout();
2104 if( pRoot )
2105 aSz = pRoot->getFrameArea().SSize();
2106
2107 return aSz;
2108}
2109
2110SfxItemPool& SwViewShell::GetAttrPool()
2111{
2112 return GetDoc()->GetAttrPool();
2113}
2114
2115void SwViewShell::ApplyViewOptions( const SwViewOption &rOpt )
2116{
2117 for(SwViewShell& rSh : GetRingContainer())
2118 rSh.StartAction();
2119
2120 ImplApplyViewOptions( rOpt );
2121
2122 // With one layout per view it is no longer necessary
2123 // to sync these "layout related" view options
2124 // But as long as we have to disable "multiple layout"
2125
2126 for(SwViewShell& rSh : GetRingContainer())
2127 {
2128 if(&rSh == this)
2129 continue;
2130 SwViewOption aOpt( *rSh.GetViewOptions() );
2131 aOpt.SetFieldName( rOpt.IsFieldName() );
2132 aOpt.SetShowHiddenField( rOpt.IsShowHiddenField() );
2133 aOpt.SetShowHiddenPara( rOpt.IsShowHiddenPara() );
2134 aOpt.SetShowHiddenChar( rOpt.IsShowHiddenChar() );
2135 aOpt.SetViewLayoutBookMode( rOpt.IsViewLayoutBookMode() );
2136 aOpt.SetHideWhitespaceMode(rOpt.IsHideWhitespaceMode());
2137 aOpt.SetViewLayoutColumns(rOpt.GetViewLayoutColumns());
2138 aOpt.SetPostIts(rOpt.IsPostIts());
2139 if ( !(aOpt == *rSh.GetViewOptions()) )
2140 rSh.ImplApplyViewOptions( aOpt );
2141 }
2142 // End of disabled multiple window
2143
2144 for(SwViewShell& rSh : GetRingContainer())
2145 rSh.EndAction();
2146}
2147
2148void SwViewShell::ImplApplyViewOptions( const SwViewOption &rOpt )
2149{
2150 if (*mpOpt == rOpt)
2151 return;
2152
2153 vcl::Window *pMyWin = GetWin();
2154 if( !pMyWin )
2155 {
2156 OSL_ENSURE( pMyWin, "SwViewShell::ApplyViewOptions: no window" )do { if (true && (!(pMyWin))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2156" ": "), "%s", "SwViewShell::ApplyViewOptions: no window"
); } } while (false)
;
2157 return;
2158 }
2159
2160 CurrShell aCurr( this );
2161
2162 bool bReformat = false;
2163
2164 if( mpOpt->IsShowHiddenField() != rOpt.IsShowHiddenField() )
2165 {
2166 static_cast<SwHiddenTextFieldType*>(mxDoc->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::HiddenText ))->
2167 SetHiddenFlag( !rOpt.IsShowHiddenField() );
2168 bReformat = true;
2169 }
2170 if ( mpOpt->IsShowHiddenPara() != rOpt.IsShowHiddenPara() )
2171 {
2172 SwHiddenParaFieldType* pFieldType = static_cast<SwHiddenParaFieldType*>(GetDoc()->
2173 getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::HiddenPara));
2174 if( pFieldType && pFieldType->HasWriterListeners() )
2175 {
2176 SwMsgPoolItem aHint( RES_HIDDENPARA_PRINT );
2177 pFieldType->ModifyNotification( &aHint, nullptr);
2178 }
2179 bReformat = true;
2180 }
2181 if ( !bReformat && mpOpt->IsShowHiddenChar() != rOpt.IsShowHiddenChar() )
2182 {
2183 bReformat = GetDoc()->ContainsHiddenChars();
2184 }
2185
2186 // bReformat becomes true, if ...
2187 // - fieldnames apply or not ...
2188 // ( - SwEndPortion must _no_ longer be generated. )
2189 // - Of course, the screen is something completely different than the printer ...
2190 bReformat = bReformat || mpOpt->IsFieldName() != rOpt.IsFieldName();
2191 bool const isEnableFieldNames(mpOpt->IsFieldName() != rOpt.IsFieldName() && rOpt.IsFieldName());
2192
2193 // The map mode is changed, minima/maxima will be attended by UI
2194 if( mpOpt->GetZoom() != rOpt.GetZoom() && !IsPreview() )
2195 {
2196 MapMode aMode( pMyWin->GetMapMode() );
2197 Fraction aNewFactor( rOpt.GetZoom(), 100 );
2198 aMode.SetScaleX( aNewFactor );
2199 aMode.SetScaleY( aNewFactor );
2200 pMyWin->SetMapMode( aMode );
2201 // if not a reference device (printer) is used for formatting,
2202 // but the screen, new formatting is needed for zoomfactor changes.
2203 if (mpOpt->getBrowseMode() || mpOpt->IsWhitespaceHidden())
2204 bReformat = true;
2205 }
2206
2207 bool bBrowseModeChanged = false;
2208 if( mpOpt->getBrowseMode() != rOpt.getBrowseMode() )
2209 {
2210 bBrowseModeChanged = true;
2211 bReformat = true;
2212 }
2213 else if( mpOpt->getBrowseMode() && mpOpt->IsPrtFormat() != rOpt.IsPrtFormat() )
2214 bReformat = true;
2215
2216 bool bHideWhitespaceModeChanged = false;
2217 if (mpOpt->IsWhitespaceHidden() != rOpt.IsWhitespaceHidden())
2218 {
2219 // When whitespace is hidden, view change needs reformatting.
2220 bHideWhitespaceModeChanged = true;
2221 bReformat = true;
2222 }
2223
2224 if ( HasDrawView() || rOpt.IsGridVisible() )
2225 {
2226 if ( !HasDrawView() )
2227 MakeDrawView();
2228
2229 SwDrawView *pDView = Imp()->GetDrawView();
2230 if ( pDView->IsDragStripes() != rOpt.IsCrossHair() )
2231 pDView->SetDragStripes( rOpt.IsCrossHair() );
2232
2233 if ( pDView->IsGridSnap() != rOpt.IsSnap() )
2234 pDView->SetGridSnap( rOpt.IsSnap() );
2235
2236 if ( pDView->IsGridVisible() != rOpt.IsGridVisible() )
2237 pDView->SetGridVisible( rOpt.IsGridVisible() );
2238
2239 const Size &rSz = rOpt.GetSnapSize();
2240 pDView->SetGridCoarse( rSz );
2241
2242 const Size aFSize
2243 ( rSz.Width() ? rSz.Width() / (rOpt.GetDivisionX()+1) : 0,
2244 rSz.Height()? rSz.Height()/ (rOpt.GetDivisionY()+1) : 0);
2245 pDView->SetGridFine( aFSize );
2246 Fraction aSnGrWdtX(rSz.Width(), rOpt.GetDivisionX() + 1);
2247 Fraction aSnGrWdtY(rSz.Height(), rOpt.GetDivisionY() + 1);
2248 pDView->SetSnapGridWidth( aSnGrWdtX, aSnGrWdtY );
2249
2250 // set handle size to 9 pixels, always
2251 pDView->SetMarkHdlSizePixel(9);
2252 }
2253
2254 bool bOnlineSpellChgd = mpOpt->IsOnlineSpell() != rOpt.IsOnlineSpell();
2255
2256 *mpOpt = rOpt; // First the options are taken.
2257 mpOpt->SetUIOptions(rOpt);
2258
2259 mxDoc->GetDocumentSettingManager().set(DocumentSettingId::HTML_MODE, 0 != ::GetHtmlMode(mxDoc->GetDocShell()));
2260
2261 if( bBrowseModeChanged || bHideWhitespaceModeChanged )
2262 {
2263 // #i44963# Good occasion to check if page sizes in
2264 // page descriptions are still set to (LONG_MAX, LONG_MAX) (html import)
2265 mxDoc->CheckDefaultPageFormat();
2266 InvalidateLayout( true );
2267 }
2268
2269 pMyWin->Invalidate();
2270 if ( bReformat )
2271 {
2272 // Nothing helps, we need to send all ContentFrames a
2273 // Prepare, we format anew:
2274 StartAction();
2275 Reformat();
2276 EndAction();
2277 }
2278
2279 if (isEnableFieldNames)
2280 {
2281 for(SwViewShell& rSh : GetRingContainer())
2282 {
2283 if (SwCursorShell *const pSh = dynamic_cast<SwCursorShell *>(&rSh))
2284 {
2285 if (pSh->CursorInsideInputField())
2286 { // move cursor out of input field
2287 pSh->Left(1, CRSR_SKIP_CHARS);
2288 }
2289 }
2290 }
2291 }
2292
2293 if( !bOnlineSpellChgd )
2294 return;
2295
2296 bool bOnlineSpl = rOpt.IsOnlineSpell();
2297 for(SwViewShell& rSh : GetRingContainer())
2298 {
2299 if(&rSh == this)
2300 continue;
2301 rSh.mpOpt->SetOnlineSpell( bOnlineSpl );
2302 vcl::Window *pTmpWin = rSh.GetWin();
2303 if( pTmpWin )
2304 pTmpWin->Invalidate();
2305 }
2306
2307}
2308
2309void SwViewShell::SetUIOptions( const SwViewOption &rOpt )
2310{
2311 mpOpt->SetUIOptions(rOpt);
2312 //the API-Flag of the view options is set but never reset
2313 //it is required to set scroll bars in readonly documents
2314 if(rOpt.IsStarOneSetting())
2315 mpOpt->SetStarOneSetting(true);
2316
2317 mpOpt->SetSymbolFont(rOpt.GetSymbolFont());
2318}
2319
2320void SwViewShell::SetReadonlyOption(bool bSet)
2321{
2322 //JP 01.02.99: at readonly flag query properly
2323 // and if need be format; Bug 61335
2324
2325 // Are we switching from readonly to edit?
2326 if( bSet == mpOpt->IsReadonly() )
1
Assuming the condition is false
2
Taking false branch
2327 return;
2328
2329 // so that the flags can be queried properly.
2330 mpOpt->SetReadonly( false );
2331
2332 bool bReformat = mpOpt->IsFieldName();
2333
2334 mpOpt->SetReadonly( bSet );
2335
2336 if( bReformat
2.1
'bReformat' is true
2.1
'bReformat' is true
2.1
'bReformat' is true
2.1
'bReformat' is true
2.1
'bReformat' is true
)
3
Taking true branch
2337 {
2338 StartAction();
2339 Reformat();
2340 if ( GetWin() )
4
Assuming the condition is true
5
Taking true branch
2341 GetWin()->Invalidate();
2342 EndAction();
6
Calling 'SwViewShell::EndAction'
2343 }
2344 else if ( GetWin() )
2345 GetWin()->Invalidate();
2346 if( Imp()->IsAccessible() )
2347 Imp()->InvalidateAccessibleEditableState( false );
2348}
2349
2350void SwViewShell::SetPDFExportOption(bool bSet)
2351{
2352 if( bSet != mpOpt->IsPDFExport() )
2353 {
2354 if( bSet && mpOpt->getBrowseMode() )
2355 mpOpt->SetPrtFormat( true );
2356 mpOpt->SetPDFExport(bSet);
2357 }
2358}
2359
2360void SwViewShell::SetReadonlySelectionOption(bool bSet)
2361{
2362 if( bSet != mpOpt->IsSelectionInReadonly() )
2363 {
2364 mpOpt->SetSelectionInReadonly(bSet);
2365 }
2366}
2367
2368void SwViewShell::SetPrtFormatOption( bool bSet )
2369{
2370 mpOpt->SetPrtFormat( bSet );
2371}
2372
2373void SwViewShell::UISizeNotify()
2374{
2375 if ( mbDocSizeChgd )
2376 {
2377 mbDocSizeChgd = false;
2378 bool bOld = bInSizeNotify;
2379 bInSizeNotify = true;
2380 ::SizeNotify( this, GetDocSize() );
2381 bInSizeNotify = bOld;
2382 }
2383}
2384
2385void SwViewShell::SetRestoreActions(sal_uInt16 nSet)
2386{
2387 OSL_ENSURE(!GetRestoreActions()||!nSet, "multiple restore of the Actions ?")do { if (true && (!(!GetRestoreActions()||!nSet))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2387" ": "), "%s", "multiple restore of the Actions ?")
; } } while (false)
;
2388 Imp()->SetRestoreActions(nSet);
2389}
2390sal_uInt16 SwViewShell::GetRestoreActions() const
2391{
2392 return Imp()->GetRestoreActions();
2393}
2394
2395bool SwViewShell::IsNewLayout() const
2396{
2397 return GetLayout()->IsNewLayout();
2398}
2399
2400uno::Reference< css::accessibility::XAccessible > SwViewShell::CreateAccessible()
2401{
2402 uno::Reference< css::accessibility::XAccessible > xAcc;
2403
2404 // We require a layout and an XModel to be accessible.
2405 OSL_ENSURE( mpLayout, "no layout, no access" )do { if (true && (!(mpLayout))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2405" ": "), "%s", "no layout, no access"); } } while (
false)
;
2406 OSL_ENSURE( GetWin(), "no window, no access" )do { if (true && (!(GetWin()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2406" ": "), "%s", "no window, no access"); } } while (
false)
;
2407
2408 if( mxDoc->getIDocumentLayoutAccess().GetCurrentViewShell() && GetWin() )
2409 xAcc = Imp()->GetAccessibleMap().GetDocumentView();
2410
2411 return xAcc;
2412}
2413
2414uno::Reference< css::accessibility::XAccessible > SwViewShell::CreateAccessiblePreview()
2415{
2416 OSL_ENSURE( IsPreview(),do { if (true && (!(IsPreview()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2417" ": "), "%s", "Can't create accessible preview for non-preview SwViewShell"
); } } while (false)
2417 "Can't create accessible preview for non-preview SwViewShell" )do { if (true && (!(IsPreview()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2417" ": "), "%s", "Can't create accessible preview for non-preview SwViewShell"
); } } while (false)
;
2418
2419 // We require a layout and an XModel to be accessible.
2420 OSL_ENSURE( mpLayout, "no layout, no access" )do { if (true && (!(mpLayout))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2420" ": "), "%s", "no layout, no access"); } } while (
false)
;
2421 OSL_ENSURE( GetWin(), "no window, no access" )do { if (true && (!(GetWin()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2421" ": "), "%s", "no window, no access"); } } while (
false)
;
2422
2423 if ( IsPreview() && GetLayout()&& GetWin() )
2424 {
2425 return Imp()->GetAccessibleMap().GetDocumentPreview(
2426 PagePreviewLayout()->maPreviewPages,
2427 GetWin()->GetMapMode().GetScaleX(),
2428 GetLayout()->GetPageByPageNum( PagePreviewLayout()->mnSelectedPageNum ),
2429 PagePreviewLayout()->maWinSize );
2430 }
2431 return nullptr;
2432}
2433
2434void SwViewShell::InvalidateAccessibleFocus()
2435{
2436 if( Imp() && Imp()->IsAccessible() )
2437 Imp()->GetAccessibleMap().InvalidateFocus();
2438}
2439
2440/**
2441 * invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs #i27138#
2442 */
2443void SwViewShell::InvalidateAccessibleParaFlowRelation( const SwTextFrame* _pFromTextFrame,
2444 const SwTextFrame* _pToTextFrame )
2445{
2446 if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
2447 {
2448 Imp()->InvalidateAccessibleParaFlowRelation_( _pFromTextFrame, _pToTextFrame );
2449 }
2450}
2451
2452/**
2453 * invalidate text selection for paragraphs #i27301#
2454 */
2455void SwViewShell::InvalidateAccessibleParaTextSelection()
2456{
2457 if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
2458 {
2459 Imp()->InvalidateAccessibleParaTextSelection_();
2460 }
2461}
2462
2463/**
2464 * invalidate attributes for paragraphs #i88069#
2465 */
2466void SwViewShell::InvalidateAccessibleParaAttrs( const SwTextFrame& rTextFrame )
2467{
2468 if ( GetLayout() && GetLayout()->IsAnyShellAccessible() )
2469 {
2470 Imp()->InvalidateAccessibleParaAttrs_( rTextFrame );
2471 }
2472}
2473
2474SwAccessibleMap* SwViewShell::GetAccessibleMap()
2475{
2476 if ( Imp()->IsAccessible() )
2477 {
2478 return &(Imp()->GetAccessibleMap());
2479 }
2480
2481 return nullptr;
2482}
2483
2484void SwViewShell::ApplyAccessibilityOptions(SvtAccessibilityOptions const & rAccessibilityOptions)
2485{
2486 if (utl::ConfigManager::IsFuzzing())
2487 return;
2488 if (mpOpt->IsPagePreview() && !rAccessibilityOptions.GetIsForPagePreviews())
2489 {
2490 mpAccOptions->SetAlwaysAutoColor(false);
2491 mpAccOptions->SetStopAnimatedGraphics(false);
2492 }
2493 else
2494 {
2495 mpAccOptions->SetAlwaysAutoColor(rAccessibilityOptions.GetIsAutomaticFontColor());
2496 mpAccOptions->SetStopAnimatedGraphics(! rAccessibilityOptions.GetIsAllowAnimatedGraphics());
2497
2498 // Form view
2499 // Always set this option, not only if document is read-only:
2500 mpOpt->SetSelectionInReadonly(rAccessibilityOptions.IsSelectionInReadonly());
2501 }
2502}
2503
2504ShellResource* SwViewShell::GetShellRes()
2505{
2506 return mpShellRes;
2507}
2508
2509void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Window>& rNew)
2510{
2511 (*mpCareDialog.get()) = rNew;
2512}
2513
2514sal_uInt16 SwViewShell::GetPageCount() const
2515{
2516 return GetLayout() ? GetLayout()->GetPageNum() : 1;
2517}
2518
2519Size SwViewShell::GetPageSize( sal_uInt16 nPageNum, bool bSkipEmptyPages ) const
2520{
2521 Size aSize;
2522 const SwRootFrame* pTmpRoot = GetLayout();
2523 if( pTmpRoot && nPageNum )
2524 {
2525 const SwPageFrame* pPage = static_cast<const SwPageFrame*>
2526 (pTmpRoot->Lower());
2527
2528 while( --nPageNum && pPage->GetNext() )
2529 pPage = static_cast<const SwPageFrame*>( pPage->GetNext() );
2530
2531 if( !bSkipEmptyPages && pPage->IsEmptyPage() && pPage->GetNext() )
2532 pPage = static_cast<const SwPageFrame*>( pPage->GetNext() );
2533
2534 aSize = pPage->getFrameArea().SSize();
2535 }
2536 return aSize;
2537}
2538
2539// #i12836# enhanced pdf export
2540sal_Int32 SwViewShell::GetPageNumAndSetOffsetForPDF( OutputDevice& rOut, const SwRect& rRect ) const
2541{
2542 OSL_ENSURE( GetLayout(), "GetPageNumAndSetOffsetForPDF assumes presence of layout" )do { if (true && (!(GetLayout()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2542" ": "), "%s", "GetPageNumAndSetOffsetForPDF assumes presence of layout"
); } } while (false)
;
2543
2544 sal_Int32 nRet = -1;
2545
2546 // #i40059# Position out of bounds:
2547 SwRect aRect( rRect );
2548 aRect.Pos().setX( std::max( aRect.Left(), GetLayout()->getFrameArea().Left() ) );
2549
2550 const SwPageFrame* pPage = GetLayout()->GetPageAtPos( aRect.Center() );
2551 if ( pPage )
2552 {
2553 OSL_ENSURE( pPage, "GetPageNumAndSetOffsetForPDF: No page found" )do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/view/viewsh.cxx"
":" "2553" ": "), "%s", "GetPageNumAndSetOffsetForPDF: No page found"
); } } while (false)
;
2554
2555 Point aOffset( pPage->getFrameArea().Pos() );
2556 aOffset.setX( -aOffset.X() );
2557 aOffset.setY( -aOffset.Y() );
2558
2559 MapMode aMapMode( rOut.GetMapMode() );
2560 aMapMode.SetOrigin( aOffset );
2561 rOut.SetMapMode( aMapMode );
2562
2563 nRet = pPage->GetPhyPageNum() - 1;
2564 }
2565
2566 return nRet;
2567}
2568
2569// --> PB 2007-05-30 #146850#
2570const BitmapEx& SwViewShell::GetReplacementBitmap( bool bIsErrorState )
2571{
2572 if (bIsErrorState)
2573 {
2574 if (!m_xErrorBmp)
2575 m_xErrorBmp.reset(new BitmapEx(RID_GRAPHIC_ERRORBMP"res/grafikde.png"));
2576 return *m_xErrorBmp;
2577 }
2578
2579 if (!m_xReplaceBmp)
2580 m_xReplaceBmp.reset(new BitmapEx(RID_GRAPHIC_REPLACEBMP"res/grafikei.png"));
2581 return *m_xReplaceBmp;
2582}
2583
2584void SwViewShell::DeleteReplacementBitmaps()
2585{
2586 m_xErrorBmp.reset();
2587 m_xReplaceBmp.reset();
2588}
2589
2590SwPostItMgr* SwViewShell::GetPostItMgr()
2591{
2592 SwView* pView = GetDoc()->GetDocShell() ? GetDoc()->GetDocShell()->GetView() : nullptr;
2593 if ( pView )
2594 return pView->GetPostItMgr();
2595
2596 return nullptr;
2597}
2598
2599/*
2600 * Document Interface Access
2601 */
2602const IDocumentSettingAccess& SwViewShell::getIDocumentSettingAccess() const { return mxDoc->GetDocumentSettingManager(); }
2603IDocumentSettingAccess& SwViewShell::getIDocumentSettingAccess() { return mxDoc->GetDocumentSettingManager(); }
2604const IDocumentDeviceAccess& SwViewShell::getIDocumentDeviceAccess() const { return mxDoc->getIDocumentDeviceAccess(); }
2605IDocumentDeviceAccess& SwViewShell::getIDocumentDeviceAccess() { return mxDoc->getIDocumentDeviceAccess(); }
2606const IDocumentMarkAccess* SwViewShell::getIDocumentMarkAccess() const { return mxDoc->getIDocumentMarkAccess(); }
2607IDocumentMarkAccess* SwViewShell::getIDocumentMarkAccess() { return mxDoc->getIDocumentMarkAccess(); }
2608const IDocumentDrawModelAccess& SwViewShell::getIDocumentDrawModelAccess() const { return mxDoc->getIDocumentDrawModelAccess(); }
2609IDocumentDrawModelAccess& SwViewShell::getIDocumentDrawModelAccess() { return mxDoc->getIDocumentDrawModelAccess(); }
2610const IDocumentRedlineAccess& SwViewShell::getIDocumentRedlineAccess() const { return mxDoc->getIDocumentRedlineAccess(); }
2611IDocumentRedlineAccess& SwViewShell::getIDocumentRedlineAccess() { return mxDoc->getIDocumentRedlineAccess(); }
2612const IDocumentLayoutAccess& SwViewShell::getIDocumentLayoutAccess() const { return mxDoc->getIDocumentLayoutAccess(); }
2613IDocumentLayoutAccess& SwViewShell::getIDocumentLayoutAccess() { return mxDoc->getIDocumentLayoutAccess(); }
2614IDocumentContentOperations& SwViewShell::getIDocumentContentOperations() { return mxDoc->getIDocumentContentOperations(); }
2615IDocumentStylePoolAccess& SwViewShell::getIDocumentStylePoolAccess() { return mxDoc->getIDocumentStylePoolAccess(); }
2616const IDocumentStatistics& SwViewShell::getIDocumentStatistics() const { return mxDoc->getIDocumentStatistics(); }
2617
2618IDocumentUndoRedo & SwViewShell::GetIDocumentUndoRedo()
2619{ return mxDoc->GetIDocumentUndoRedo(); }
2620IDocumentUndoRedo const& SwViewShell::GetIDocumentUndoRedo() const
2621{ return mxDoc->GetIDocumentUndoRedo(); }
2622
2623// --> OD 2007-11-14 #i83479#
2624const IDocumentListItems* SwViewShell::getIDocumentListItemsAccess() const
2625{
2626 return &mxDoc->getIDocumentListItems();
2627}
2628
2629const IDocumentOutlineNodes* SwViewShell::getIDocumentOutlineNodesAccess() const
2630{
2631 return &mxDoc->getIDocumentOutlineNodes();
2632}
2633
2634/* 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; }
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) )
7
Taking true branch
597 ImplEndAction( bIdleEnd );
8
Calling 'SwViewShell::ImplEndAction'
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/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)
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 );
28
Memory is allocated
130 }
131
132 /** Probably most common used: handle->someBodyOp().
133 */
134 reference_type * operator->() const
135 {
136 return m_rInnerRef.get();
41
Calling 'Reference::get'
137 }
138
139 /** Get the body. Can be used instead of operator->().
140 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
141 are the same.
142 */
143 reference_type * get() const
144 {
145 return m_rInnerRef.get();
146 }
147
148 void set(reference_type *pBody)
149 {
150 m_rInnerRef.set(pBody);
151 }
152
153 void reset(reference_type *pBody)
154 {
155 m_rInnerRef.set(pBody);
156 }
157
158 /** Up-casting copy assignment operator.
159
160 Does not work for up-casts to ambiguous bases.
161
162 @param rRef another reference
163 */
164 template<typename derived_type>
165 typename std::enable_if<
166 std::is_base_of<reference_type, derived_type>::value,
167 VclPtr &>::type
168 operator =(VclPtr<derived_type> const & rRef)
169 {
170 m_rInnerRef.set(rRef.get());
171 return *this;
172 }
173
174 VclPtr & operator =(reference_type * pBody)
175 {
176 m_rInnerRef.set(pBody);
177 return *this;
178 }
179
180 operator reference_type * () const
181 {
182 return m_rInnerRef.get();
183 }
184
185 explicit operator bool () const
186 {
187 return m_rInnerRef.get() != nullptr;
188 }
189
190 void clear()
191 {
192 m_rInnerRef.clear();
193 }
194
195 void reset()
196 {
197 m_rInnerRef.clear();
198 }
199
200 void disposeAndClear()
201 {
202 // hold it alive for the lifetime of this method
203 ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
204 m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
205 if (aTmp.get()) {
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
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
31.1
Field 'm_pBody' is non-null
31.1
Field 'm_pBody' is non-null
31.1
Field 'm_pBody' is non-null
31.1
Field 'm_pBody' is non-null
31.1
Field 'm_pBody' is non-null
)
32
Taking true branch
113 m_pBody->release();
33
Calling 'VclReferenceBase::release'
37
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
42
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/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)
34
Assuming the condition is true
35
Taking true branch
40 delete this;
36
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