File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||||||||
84 | bool SwViewShell::mbLstAct = false; | ||||||||||
85 | ShellResource *SwViewShell::mpShellRes = nullptr; | ||||||||||
86 | vcl::DeleteOnDeinit<std::shared_ptr<weld::Window>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Window>); | ||||||||||
87 | |||||||||||
88 | static bool bInSizeNotify = false; | ||||||||||
89 | |||||||||||
90 | |||||||||||
91 | using namespace ::com::sun::star; | ||||||||||
92 | |||||||||||
93 | void 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 | |||||||||||
105 | void 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 | |||||||||||
126 | void SwViewShell::setOutputToWindow(bool bOutputToWindow) | ||||||||||
127 | { | ||||||||||
128 | mbOutputToWindow = bOutputToWindow; | ||||||||||
129 | } | ||||||||||
130 | |||||||||||
131 | bool SwViewShell::isOutputToWindow() const | ||||||||||
132 | { | ||||||||||
133 | return mbOutputToWindow; | ||||||||||
134 | } | ||||||||||
135 | |||||||||||
136 | void SwViewShell::dumpAsXml(xmlTextWriterPtr pWriter) const | ||||||||||
137 | { | ||||||||||
138 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SwViewShell")); | ||||||||||
139 | xmlTextWriterEndElement(pWriter); | ||||||||||
140 | } | ||||||||||
141 | |||||||||||
142 | static void | ||||||||||
143 | lcl_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 | |||||||||||
163 | void SwViewShell::PrePaint() | ||||||||||
164 | { | ||||||||||
165 | // forward PrePaint event from VCL Window to DrawingLayer | ||||||||||
166 | if(HasDrawView()) | ||||||||||
167 | { | ||||||||||
168 | Imp()->GetDrawView()->PrePaint(); | ||||||||||
169 | } | ||||||||||
170 | } | ||||||||||
171 | |||||||||||
172 | void 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 | |||||||||||
211 | void 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 | |||||||||||
239 | void SwViewShell::ImplEndAction( const bool bIdleEnd ) | ||||||||||
240 | { | ||||||||||
241 | // Nothing to do for the printer? | ||||||||||
242 | if ( !GetWin() || IsPreview() ) | ||||||||||
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() ); | ||||||||||
269 | |||||||||||
270 | CurrShell aCurr( this ); | ||||||||||
271 | if ( Imp()->HasDrawView() && !Imp()->GetDrawView()->areMarkHandlesHidden() ) | ||||||||||
272 | Imp()->StartAction(); | ||||||||||
273 | |||||||||||
274 | if ( Imp()->GetRegion() && Imp()->GetRegion()->GetOrigin() != VisArea() ) | ||||||||||
275 | Imp()->DelRegion(); | ||||||||||
276 | |||||||||||
277 | const bool bExtraData = ::IsExtraData( GetDoc() ); | ||||||||||
278 | |||||||||||
279 | if ( !bIdleEnd
| ||||||||||
280 | { | ||||||||||
281 | SwLayAction aAction( GetLayout(), Imp() ); | ||||||||||
282 | aAction.SetComplete( false ); | ||||||||||
283 | if ( mnLockPaint ) | ||||||||||
284 | aAction.SetPaint( false ); | ||||||||||
285 | aAction.Action(GetWin()); | ||||||||||
286 | } | ||||||||||
287 | |||||||||||
288 | if ( bIsShellForCheckViewLayout
| ||||||||||
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() || | ||||||||||
294 | maInvalidRect.HasArea() || | ||||||||||
295 | bExtraData ) | ||||||||||
296 | { | ||||||||||
297 | if ( !mnLockPaint
| ||||||||||
298 | { | ||||||||||
299 | SolarMutexGuard aGuard; | ||||||||||
300 | |||||||||||
301 | bool bPaintsFromSystem = maInvalidRect.HasArea(); | ||||||||||
302 | GetWin()->PaintImmediately(); | ||||||||||
303 | if ( maInvalidRect.HasArea() ) | ||||||||||
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
| ||||||||||
322 | static_cast<SwCursorShell*>(this)->HideCursors(); | ||||||||||
323 | |||||||||||
324 | if ( pRegion ) | ||||||||||
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() ) | ||||||||||
335 | { | ||||||||||
336 | SwRect aRect( pRegion->back() ); | ||||||||||
337 | pRegion->pop_back(); | ||||||||||
338 | |||||||||||
339 | bool bPaint = true; | ||||||||||
340 | if ( IsEndActionByVirDev() ) | ||||||||||
341 | { | ||||||||||
342 | //create virtual device and set. | ||||||||||
343 | if ( !pVout ) | ||||||||||
344 | pVout = VclPtr<VirtualDevice>::Create( *GetOut() ); | ||||||||||
345 | MapMode aMapMode( GetOut()->GetMapMode() ); | ||||||||||
346 | pVout->SetMapMode( aMapMode ); | ||||||||||
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 | |||||||||||
455 | void SwViewShell::ImplStartAction() | ||||||||||
456 | { | ||||||||||
457 | mbPaintWorks = false; | ||||||||||
458 | Imp()->StartAction(); | ||||||||||
459 | } | ||||||||||
460 | |||||||||||
461 | void SwViewShell::ImplLockPaint() | ||||||||||
462 | { | ||||||||||
463 | if ( GetWin() && GetWin()->IsVisible() ) | ||||||||||
464 | GetWin()->EnablePaint( false ); //Also cut off the controls. | ||||||||||
465 | Imp()->LockPaint(); | ||||||||||
466 | } | ||||||||||
467 | |||||||||||
468 | void 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 | |||||||||||
525 | bool 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 | |||||||||||
541 | void 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 | |||||||||||
560 | const 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 | |||||||||||
567 | void 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 | |||||||||||
597 | weld::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 | |||||||||||
617 | Point SwViewShell::GetPagePos( sal_uInt16 nPageNum ) const | ||||||||||
618 | { | ||||||||||
619 | return GetLayout()->GetPagePos( nPageNum ); | ||||||||||
620 | } | ||||||||||
621 | |||||||||||
622 | sal_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 | |||||||||||
629 | bool 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 | */ | ||||||||||
640 | void 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 */ | ||||||||||
659 | void SwViewShell::UpdateAllCharts() | ||||||||||
660 | { | ||||||||||
661 | CurrShell aCurr( this ); | ||||||||||
662 | // Start-/EndAction handled in the SwDoc-Method! | ||||||||||
663 | GetDoc()->UpdateAllCharts(); | ||||||||||
664 | } | ||||||||||
665 | |||||||||||
666 | bool 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 | |||||||||||
684 | void 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 | |||||||||||
717 | static 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 | */ | ||||||||||
737 | static 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 | |||||||||||
755 | void 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 | |||||||||||
767 | void 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 | |||||||||||
779 | void 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 | |||||||||||
791 | void 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 | |||||||||||
806 | void 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 | */ | ||||||||||
822 | void 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 | */ | ||||||||||
842 | void 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 | */ | ||||||||||
859 | void 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# | ||||||||||
871 | void 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 | |||||||||||
882 | void 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# | ||||||||||
895 | void 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 | |||||||||||
907 | void SwViewShell::SetProtectForm( bool _bProtectForm ) | ||||||||||
908 | { | ||||||||||
909 | IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess(); | ||||||||||
910 | rIDSA.set(DocumentSettingId::PROTECT_FORM, _bProtectForm ); | ||||||||||
911 | } | ||||||||||
912 | |||||||||||
913 | void 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 | |||||||||||
925 | void SwViewShell::SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys) | ||||||||||
926 | { | ||||||||||
927 | IDocumentSettingAccess& rIDSA = getIDocumentSettingAccess(); | ||||||||||
928 | rIDSA.set(DocumentSettingId::SUBTRACT_FLYS, bSubtractFlysAnchoredAtFlys); | ||||||||||
929 | } | ||||||||||
930 | |||||||||||
931 | void 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 | |||||||||||
951 | void 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 | |||||||||||
968 | void SwViewShell::ChgNumberDigits() | ||||||||||
969 | { | ||||||||||
970 | SdrModel* pTmpDrawModel = getIDocumentDrawModelAccess().GetDrawModel(); | ||||||||||
971 | if ( pTmpDrawModel ) | ||||||||||
972 | pTmpDrawModel->ReformatAllTextObjects(); | ||||||||||
973 | Reformat(); | ||||||||||
974 | } | ||||||||||
975 | |||||||||||
976 | void 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 | |||||||||||
1028 | void SwViewShell::SetFirstVisPageInvalid() | ||||||||||
1029 | { | ||||||||||
1030 | for(SwViewShell& rSh : GetRingContainer()) | ||||||||||
1031 | { | ||||||||||
1032 | if ( rSh.Imp() ) | ||||||||||
1033 | rSh.Imp()->SetFirstVisPageInvalid(); | ||||||||||
1034 | } | ||||||||||
1035 | } | ||||||||||
1036 | |||||||||||
1037 | void 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 | |||||||||||
1076 | void 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 | |||||||||||
1247 | bool 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 | |||||||||||
1480 | void 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 | ||||||||||
1562 | void 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 | |||||||||||
1613 | bool 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 | |||||||||||
1715 | namespace | ||||||||||
1716 | { | ||||||||||
1717 | /// Similar to comphelper::FlagRestorationGuard, but for vcl::RenderContext. | ||||||||||
1718 | class RenderContextGuard | ||||||||||
1719 | { | ||||||||||
1720 | std::unique_ptr<SdrPaintWindow> m_TemporaryPaintWindow; | ||||||||||
1721 | SdrPageWindow* m_pPatchedPageWindow; | ||||||||||
1722 | SdrPaintWindow* m_pPreviousPaintWindow = nullptr; | ||||||||||
1723 | |||||||||||
1724 | public: | ||||||||||
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 | |||||||||||
1762 | void 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 | |||||||||||
1896 | void 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 | |||||||||||
1987 | void SwViewShell::SetBrowseBorder( const Size& rNew ) | ||||||||||
1988 | { | ||||||||||
1989 | if( rNew != maBrowseBorder ) | ||||||||||
1990 | { | ||||||||||
1991 | maBrowseBorder = rNew; | ||||||||||
1992 | if ( maVisArea.HasArea() ) | ||||||||||
1993 | InvalidateLayout( false ); | ||||||||||
1994 | } | ||||||||||
1995 | } | ||||||||||
1996 | |||||||||||
1997 | const Size& SwViewShell::GetBrowseBorder() const | ||||||||||
1998 | { | ||||||||||
1999 | return maBrowseBorder; | ||||||||||
2000 | } | ||||||||||
2001 | |||||||||||
2002 | sal_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 | |||||||||||
2016 | void 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 | |||||||||||
2073 | SwRootFrame *SwViewShell::GetLayout() const | ||||||||||
2074 | { | ||||||||||
2075 | return mpLayout.get(); | ||||||||||
2076 | } | ||||||||||
2077 | |||||||||||
2078 | vcl::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 | |||||||||||
2091 | const SwNodes& SwViewShell::GetNodes() const | ||||||||||
2092 | { | ||||||||||
2093 | return mxDoc->GetNodes(); | ||||||||||
2094 | } | ||||||||||
2095 | |||||||||||
2096 | void SwViewShell::DrawSelChanged() | ||||||||||
2097 | { | ||||||||||
2098 | } | ||||||||||
2099 | |||||||||||
2100 | Size 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 | |||||||||||
2110 | SfxItemPool& SwViewShell::GetAttrPool() | ||||||||||
2111 | { | ||||||||||
2112 | return GetDoc()->GetAttrPool(); | ||||||||||
2113 | } | ||||||||||
2114 | |||||||||||
2115 | void 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 | |||||||||||
2148 | void 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 | |||||||||||
2309 | void 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 | |||||||||||
2320 | void 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() ) | ||||||||||
| |||||||||||
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
| ||||||||||
2337 | { | ||||||||||
2338 | StartAction(); | ||||||||||
2339 | Reformat(); | ||||||||||
2340 | if ( GetWin() ) | ||||||||||
2341 | GetWin()->Invalidate(); | ||||||||||
2342 | EndAction(); | ||||||||||
2343 | } | ||||||||||
2344 | else if ( GetWin() ) | ||||||||||
2345 | GetWin()->Invalidate(); | ||||||||||
2346 | if( Imp()->IsAccessible() ) | ||||||||||
2347 | Imp()->InvalidateAccessibleEditableState( false ); | ||||||||||
2348 | } | ||||||||||
2349 | |||||||||||
2350 | void 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 | |||||||||||
2360 | void SwViewShell::SetReadonlySelectionOption(bool bSet) | ||||||||||
2361 | { | ||||||||||
2362 | if( bSet != mpOpt->IsSelectionInReadonly() ) | ||||||||||
2363 | { | ||||||||||
2364 | mpOpt->SetSelectionInReadonly(bSet); | ||||||||||
2365 | } | ||||||||||
2366 | } | ||||||||||
2367 | |||||||||||
2368 | void SwViewShell::SetPrtFormatOption( bool bSet ) | ||||||||||
2369 | { | ||||||||||
2370 | mpOpt->SetPrtFormat( bSet ); | ||||||||||
2371 | } | ||||||||||
2372 | |||||||||||
2373 | void 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 | |||||||||||
2385 | void 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 | } | ||||||||||
2390 | sal_uInt16 SwViewShell::GetRestoreActions() const | ||||||||||
2391 | { | ||||||||||
2392 | return Imp()->GetRestoreActions(); | ||||||||||
2393 | } | ||||||||||
2394 | |||||||||||
2395 | bool SwViewShell::IsNewLayout() const | ||||||||||
2396 | { | ||||||||||
2397 | return GetLayout()->IsNewLayout(); | ||||||||||
2398 | } | ||||||||||
2399 | |||||||||||
2400 | uno::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 | |||||||||||
2414 | uno::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 | |||||||||||
2434 | void 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 | */ | ||||||||||
2443 | void 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 | */ | ||||||||||
2455 | void SwViewShell::InvalidateAccessibleParaTextSelection() | ||||||||||
2456 | { | ||||||||||
2457 | if ( GetLayout() && GetLayout()->IsAnyShellAccessible() ) | ||||||||||
2458 | { | ||||||||||
2459 | Imp()->InvalidateAccessibleParaTextSelection_(); | ||||||||||
2460 | } | ||||||||||
2461 | } | ||||||||||
2462 | |||||||||||
2463 | /** | ||||||||||
2464 | * invalidate attributes for paragraphs #i88069# | ||||||||||
2465 | */ | ||||||||||
2466 | void SwViewShell::InvalidateAccessibleParaAttrs( const SwTextFrame& rTextFrame ) | ||||||||||
2467 | { | ||||||||||
2468 | if ( GetLayout() && GetLayout()->IsAnyShellAccessible() ) | ||||||||||
2469 | { | ||||||||||
2470 | Imp()->InvalidateAccessibleParaAttrs_( rTextFrame ); | ||||||||||
2471 | } | ||||||||||
2472 | } | ||||||||||
2473 | |||||||||||
2474 | SwAccessibleMap* SwViewShell::GetAccessibleMap() | ||||||||||
2475 | { | ||||||||||
2476 | if ( Imp()->IsAccessible() ) | ||||||||||
2477 | { | ||||||||||
2478 | return &(Imp()->GetAccessibleMap()); | ||||||||||
2479 | } | ||||||||||
2480 | |||||||||||
2481 | return nullptr; | ||||||||||
2482 | } | ||||||||||
2483 | |||||||||||
2484 | void 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 | |||||||||||
2504 | ShellResource* SwViewShell::GetShellRes() | ||||||||||
2505 | { | ||||||||||
2506 | return mpShellRes; | ||||||||||
2507 | } | ||||||||||
2508 | |||||||||||
2509 | void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Window>& rNew) | ||||||||||
2510 | { | ||||||||||
2511 | (*mpCareDialog.get()) = rNew; | ||||||||||
2512 | } | ||||||||||
2513 | |||||||||||
2514 | sal_uInt16 SwViewShell::GetPageCount() const | ||||||||||
2515 | { | ||||||||||
2516 | return GetLayout() ? GetLayout()->GetPageNum() : 1; | ||||||||||
2517 | } | ||||||||||
2518 | |||||||||||
2519 | Size 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 | ||||||||||
2540 | sal_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# | ||||||||||
2570 | const 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 | |||||||||||
2584 | void SwViewShell::DeleteReplacementBitmaps() | ||||||||||
2585 | { | ||||||||||
2586 | m_xErrorBmp.reset(); | ||||||||||
2587 | m_xReplaceBmp.reset(); | ||||||||||
2588 | } | ||||||||||
2589 | |||||||||||
2590 | SwPostItMgr* 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 | */ | ||||||||||
2602 | const IDocumentSettingAccess& SwViewShell::getIDocumentSettingAccess() const { return mxDoc->GetDocumentSettingManager(); } | ||||||||||
2603 | IDocumentSettingAccess& SwViewShell::getIDocumentSettingAccess() { return mxDoc->GetDocumentSettingManager(); } | ||||||||||
2604 | const IDocumentDeviceAccess& SwViewShell::getIDocumentDeviceAccess() const { return mxDoc->getIDocumentDeviceAccess(); } | ||||||||||
2605 | IDocumentDeviceAccess& SwViewShell::getIDocumentDeviceAccess() { return mxDoc->getIDocumentDeviceAccess(); } | ||||||||||
2606 | const IDocumentMarkAccess* SwViewShell::getIDocumentMarkAccess() const { return mxDoc->getIDocumentMarkAccess(); } | ||||||||||
2607 | IDocumentMarkAccess* SwViewShell::getIDocumentMarkAccess() { return mxDoc->getIDocumentMarkAccess(); } | ||||||||||
2608 | const IDocumentDrawModelAccess& SwViewShell::getIDocumentDrawModelAccess() const { return mxDoc->getIDocumentDrawModelAccess(); } | ||||||||||
2609 | IDocumentDrawModelAccess& SwViewShell::getIDocumentDrawModelAccess() { return mxDoc->getIDocumentDrawModelAccess(); } | ||||||||||
2610 | const IDocumentRedlineAccess& SwViewShell::getIDocumentRedlineAccess() const { return mxDoc->getIDocumentRedlineAccess(); } | ||||||||||
2611 | IDocumentRedlineAccess& SwViewShell::getIDocumentRedlineAccess() { return mxDoc->getIDocumentRedlineAccess(); } | ||||||||||
2612 | const IDocumentLayoutAccess& SwViewShell::getIDocumentLayoutAccess() const { return mxDoc->getIDocumentLayoutAccess(); } | ||||||||||
2613 | IDocumentLayoutAccess& SwViewShell::getIDocumentLayoutAccess() { return mxDoc->getIDocumentLayoutAccess(); } | ||||||||||
2614 | IDocumentContentOperations& SwViewShell::getIDocumentContentOperations() { return mxDoc->getIDocumentContentOperations(); } | ||||||||||
2615 | IDocumentStylePoolAccess& SwViewShell::getIDocumentStylePoolAccess() { return mxDoc->getIDocumentStylePoolAccess(); } | ||||||||||
2616 | const IDocumentStatistics& SwViewShell::getIDocumentStatistics() const { return mxDoc->getIDocumentStatistics(); } | ||||||||||
2617 | |||||||||||
2618 | IDocumentUndoRedo & SwViewShell::GetIDocumentUndoRedo() | ||||||||||
2619 | { return mxDoc->GetIDocumentUndoRedo(); } | ||||||||||
2620 | IDocumentUndoRedo const& SwViewShell::GetIDocumentUndoRedo() const | ||||||||||
2621 | { return mxDoc->GetIDocumentUndoRedo(); } | ||||||||||
2622 | |||||||||||
2623 | // --> OD 2007-11-14 #i83479# | ||||||||||
2624 | const IDocumentListItems* SwViewShell::getIDocumentListItemsAccess() const | ||||||||||
2625 | { | ||||||||||
2626 | return &mxDoc->getIDocumentListItems(); | ||||||||||
2627 | } | ||||||||||
2628 | |||||||||||
2629 | const IDocumentOutlineNodes* SwViewShell::getIDocumentOutlineNodesAccess() const | ||||||||||
2630 | { | ||||||||||
2631 | return &mxDoc->getIDocumentOutlineNodes(); | ||||||||||
2632 | } | ||||||||||
2633 | |||||||||||
2634 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | |
33 | namespace com::sun::star::accessibility { class XAccessible; } |
34 | class SwDoc; |
35 | class IDocumentSettingAccess; |
36 | class IDocumentDeviceAccess; |
37 | class IDocumentMarkAccess; |
38 | class IDocumentDrawModelAccess; |
39 | class IDocumentRedlineAccess; |
40 | class IDocumentLayoutAccess; |
41 | class IDocumentContentOperations; |
42 | class IDocumentStylePoolAccess; |
43 | class IDocumentStatistics; |
44 | class IDocumentUndoRedo; |
45 | class IDocumentListItems; |
46 | class IDocumentOutlineNodes; |
47 | class SfxPrinter; |
48 | class SwRootFrame; |
49 | class SwNodes; |
50 | class SdrView; |
51 | class SfxItemPool; |
52 | class SfxViewShell; |
53 | class SwViewOption; |
54 | class SwViewShellImp; |
55 | class SwPrintData; |
56 | struct ShellResource; |
57 | class SwRegionRects; |
58 | class SvtAccessibilityOptions; |
59 | class SwPagePreviewLayout; |
60 | class SwTextFrame; |
61 | |
62 | struct SwAccessibilityOptions; |
63 | namespace vcl { class Region; } |
64 | class SwPostItMgr; |
65 | class SdrPaintWindow; |
66 | class SwAccessibleMap; |
67 | enum class Orientation; |
68 | |
69 | namespace 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)) |
78 | typedef std::shared_ptr<SwRootFrame> SwRootFramePtr; |
79 | |
80 | typedef struct _xmlTextWriter* xmlTextWriterPtr; |
81 | |
82 | class 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 | |
165 | protected: |
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 | |
180 | public: |
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 |
219 | protected: |
220 | std::stack<vcl::Region> mPrePostPaintRegions; // acts also as a lock counter (empty == not locked) |
221 | VclPtr<OutputDevice> mpPrePostOutDev; |
222 | MapMode maPrePostMapMode; |
223 | public: |
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 |
574 | class CurrShell |
575 | { |
576 | public: |
577 | SwViewShell *pPrev; |
578 | SwRootFrame *pRoot; |
579 | |
580 | CurrShell( SwViewShell *pNew ); |
581 | ~CurrShell(); |
582 | }; |
583 | |
584 | inline void SwViewShell::ResetInvalidRect() |
585 | { |
586 | maInvalidRect.Clear(); |
587 | } |
588 | |
589 | inline void SwViewShell::StartAction() |
590 | { |
591 | if ( !mnStartAction++ ) |
592 | ImplStartAction(); |
593 | } |
594 | inline void SwViewShell::EndAction( const bool bIdleEnd ) |
595 | { |
596 | if( 0 == (mnStartAction - 1) ) |
597 | ImplEndAction( bIdleEnd ); |
598 | --mnStartAction; |
599 | } |
600 | |
601 | inline void SwViewShell::LockPaint() |
602 | { |
603 | if ( !mnLockPaint++ ) |
604 | ImplLockPaint(); |
605 | } |
606 | inline void SwViewShell::UnlockPaint( bool bVirDev ) |
607 | { |
608 | if ( 0 == --mnLockPaint ) |
609 | ImplUnlockPaint( bVirDev ); |
610 | } |
611 | inline 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: */ |
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 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<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 | */ |
56 | template <class reference_type> |
57 | class 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 | |
66 | public: |
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 ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<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 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
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 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
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 | |
378 | private: |
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 | |
387 | protected: |
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 |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
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 | |
421 | private: |
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: */ |
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 | |||||||||||
34 | namespace rtl | ||||||||||
35 | { | ||||||||||
36 | |||||||||||
37 | /** Template reference class for reference type. | ||||||||||
38 | */ | ||||||||||
39 | template <class reference_type> | ||||||||||
40 | class Reference | ||||||||||
41 | { | ||||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||||
43 | */ | ||||||||||
44 | reference_type * m_pBody; | ||||||||||
45 | |||||||||||
46 | |||||||||||
47 | public: | ||||||||||
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
| ||||||||||
113 | m_pBody->release(); | ||||||||||
114 | } | ||||||||||
115 | |||||||||||
116 | /** Set... | ||||||||||
117 | Similar to assignment. | ||||||||||
118 | */ | ||||||||||
119 | Reference<reference_type> & | ||||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||||
121 | { | ||||||||||
122 | if (pBody) | ||||||||||
123 | pBody->acquire(); | ||||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||||
125 | m_pBody = pBody; | ||||||||||
126 | if (pOld) | ||||||||||
127 | pOld->release(); | ||||||||||
128 | return *this; | ||||||||||
129 | } | ||||||||||
130 | |||||||||||
131 | /** Assignment. | ||||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||||
133 | bind it to the body represented by the handle. | ||||||||||
134 | */ | ||||||||||
135 | Reference<reference_type> & | ||||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||||
137 | { | ||||||||||
138 | return set( handle.m_pBody ); | ||||||||||
139 | } | ||||||||||
140 | |||||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||
142 | /** Assignment. | ||||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||||
144 | * bind it to the body represented by the handle, and | ||||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||||
146 | */ | ||||||||||
147 | Reference<reference_type> & | ||||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||||
149 | { | ||||||||||
150 | // self-movement guts ourself | ||||||||||
151 | if (m_pBody) | ||||||||||
152 | m_pBody->release(); | ||||||||||
153 | m_pBody = handle.m_pBody; | ||||||||||
154 | handle.m_pBody = nullptr; | ||||||||||
155 | return *this; | ||||||||||
156 | } | ||||||||||
157 | #endif | ||||||||||
158 | |||||||||||
159 | /** Assignment... | ||||||||||
160 | */ | ||||||||||
161 | Reference<reference_type> & | ||||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||||
163 | { | ||||||||||
164 | return set( pBody ); | ||||||||||
165 | } | ||||||||||
166 | |||||||||||
167 | /** Unbind the body from this handle. | ||||||||||
168 | Note that for a handle representing a large body, | ||||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||||
171 | since in the second case two large objects exist in memory | ||||||||||
172 | (the old body and the new body). | ||||||||||
173 | */ | ||||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||||
175 | { | ||||||||||
176 | if (m_pBody) | ||||||||||
177 | { | ||||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||||
179 | m_pBody = NULL__null; | ||||||||||
180 | pOld->release(); | ||||||||||
181 | } | ||||||||||
182 | return *this; | ||||||||||
183 | } | ||||||||||
184 | |||||||||||
185 | |||||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||||
188 | are the same. | ||||||||||
189 | */ | ||||||||||
190 | reference_type * SAL_CALL get() const | ||||||||||
191 | { | ||||||||||
192 | return m_pBody; | ||||||||||
| |||||||||||
193 | } | ||||||||||
194 | |||||||||||
195 | |||||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||||
197 | */ | ||||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||||
199 | { | ||||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||||
201 | return m_pBody; | ||||||||||
202 | } | ||||||||||
203 | |||||||||||
204 | |||||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||||
206 | */ | ||||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||||
208 | { | ||||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||||
210 | return *m_pBody; | ||||||||||
211 | } | ||||||||||
212 | |||||||||||
213 | |||||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||||
215 | */ | ||||||||||
216 | bool SAL_CALL is() const | ||||||||||
217 | { | ||||||||||
218 | return (m_pBody != NULL__null); | ||||||||||
219 | } | ||||||||||
220 | |||||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||||
223 | */ | ||||||||||
224 | explicit operator bool() const | ||||||||||
225 | { | ||||||||||
226 | return is(); | ||||||||||
227 | } | ||||||||||
228 | #endif | ||||||||||
229 | |||||||||||
230 | /** Returns True if this points to pBody. | ||||||||||
231 | */ | ||||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||||
233 | { | ||||||||||
234 | return (m_pBody == pBody); | ||||||||||
235 | } | ||||||||||
236 | |||||||||||
237 | |||||||||||
238 | /** Returns True if handle points to the same body. | ||||||||||
239 | */ | ||||||||||
240 | bool | ||||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||||
242 | { | ||||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||||
244 | } | ||||||||||
245 | |||||||||||
246 | |||||||||||
247 | /** Needed to place References into STL collection. | ||||||||||
248 | */ | ||||||||||
249 | bool | ||||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||||
251 | { | ||||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||||
253 | } | ||||||||||
254 | |||||||||||
255 | |||||||||||
256 | /** Needed to place References into STL collection. | ||||||||||
257 | */ | ||||||||||
258 | bool | ||||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||||
260 | { | ||||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||||
262 | } | ||||||||||
263 | |||||||||||
264 | |||||||||||
265 | /** Needed to place References into STL collection. | ||||||||||
266 | */ | ||||||||||
267 | bool | ||||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||||
269 | { | ||||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||||
271 | } | ||||||||||
272 | }; | ||||||||||
273 | |||||||||||
274 | } // namespace rtl | ||||||||||
275 | |||||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||
277 | namespace 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 | */ | ||||||||||
286 | template<typename T> | ||||||||||
287 | struct 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: */ |
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 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
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) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |