Bug Summary

File:home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx
Warning:line 810, column 63
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sdwindow.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SD_DLLIMPLEMENTATION -D SDUI_DLL_NAME="libsduilo.so" -D SYSTEM_LIBXML -D ENABLE_SDREMOTE -D ENABLE_SDREMOTE_BLUETOOTH -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/external/bluez_bluetooth/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/sd/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sd/sdi -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <Window.hxx>
21#include <sfx2/bindings.hxx>
22#include <sfx2/request.hxx>
23
24#include <sfx2/viewfrm.hxx>
25#include <svx/svxids.hrc>
26
27#include <editeng/outliner.hxx>
28#include <editeng/editview.hxx>
29#include <editeng/editeng.hxx>
30
31#include <app.hrc>
32#include <ViewShell.hxx>
33#include <DrawViewShell.hxx>
34#include <DrawDocShell.hxx>
35#include <PresentationViewShell.hxx>
36#include <View.hxx>
37#include <FrameView.hxx>
38#include <OutlineViewShell.hxx>
39#include <drawdoc.hxx>
40#include <WindowUpdater.hxx>
41#include <ViewShellBase.hxx>
42#include <uiobject.hxx>
43
44#include <sal/log.hxx>
45#include <tools/debug.hxx>
46#include <vcl/commandevent.hxx>
47#include <vcl/settings.hxx>
48#include <comphelper/lok.hxx>
49#include <sfx2/lokhelper.hxx>
50
51namespace sd {
52
53#define SCROLL_LINE_FACT0.05 0.05 ///< factor for line scrolling
54#define SCROLL_PAGE_FACT0.5 0.5 ///< factor for page scrolling
55#define SCROLL_SENSITIVE20 20 ///< sensitive area in pixel
56#define ZOOM_MULTIPLICATOR10000 10000 ///< multiplier to avoid rounding errors
57#define MIN_ZOOM5 5 ///< minimal zoom factor
58#define MAX_ZOOM3000 3000 ///< maximal zoom factor
59
60Window::Window(vcl::Window* pParent)
61 : vcl::Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
62 DropTargetHelper( this ),
63 maWinPos(0, 0), // precautionary; but the values should be set
64 maViewOrigin(0, 0), // again from the owner of the window
65 maViewSize(1000, 1000),
66 maPrevSize(-1,-1),
67 mnMinZoom(MIN_ZOOM5),
68 mnMaxZoom(MAX_ZOOM3000),
69 mbMinZoomAutoCalc(false),
70 mbCenterAllowed(true),
71 mnTicks (0),
72 mpViewShell(nullptr),
73 mbUseDropScroll (true)
74{
75 SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus );
76
77 MapMode aMap(GetMapMode());
78 aMap.SetMapUnit(MapUnit::Map100thMM);
79 SetMapMode(aMap);
80
81 // with it, the vcl::WindowColor is used in the slide mode
82 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetWindowColor() ) );
83
84 // adjust contrast mode initially
85 bool bUseContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
86 SetDrawMode( bUseContrast
87 ? sd::OUTPUT_DRAWMODE_CONTRAST
88 : sd::OUTPUT_DRAWMODE_COLOR );
89
90 // #i78183# Added after discussed with AF
91 EnableRTL(false);
92}
93
94Window::~Window()
95{
96 disposeOnce();
97}
98
99void Window::dispose()
100{
101 if (mpViewShell != nullptr)
102 {
103 WindowUpdater* pWindowUpdater = mpViewShell->GetWindowUpdater();
104 if (pWindowUpdater != nullptr)
105 pWindowUpdater->UnregisterWindow (this);
106 }
107 DropTargetHelper::dispose();
108 vcl::Window::dispose();
109}
110
111void Window::SetViewShell (ViewShell* pViewSh)
112{
113 WindowUpdater* pWindowUpdater = nullptr;
114 // Unregister at device updater of old view shell.
115 if (mpViewShell != nullptr)
116 {
117 pWindowUpdater = mpViewShell->GetWindowUpdater();
118 if (pWindowUpdater != nullptr)
119 pWindowUpdater->UnregisterWindow (this);
120 }
121
122 mpViewShell = pViewSh;
123
124 // Register at device updater of new view shell
125 if (mpViewShell != nullptr)
126 {
127 pWindowUpdater = mpViewShell->GetWindowUpdater();
128 if (pWindowUpdater != nullptr)
129 pWindowUpdater->RegisterWindow (this);
130 }
131}
132
133ViewShell* Window::GetViewShell()
134{
135 return mpViewShell;
136}
137
138void Window::CalcMinZoom()
139{
140 // Are we entitled to change the minimal zoom factor?
141 if ( !mbMinZoomAutoCalc )
142 return;
143
144 // Get current zoom factor.
145 long nZoom = GetZoom();
146
147 // Get the rectangle of the output area in logical coordinates
148 // and calculate the scaling factors that would lead to the view
149 // area (also called application area) to completely fill the
150 // window.
151 Size aWinSize = PixelToLogic(GetOutputSizePixel());
152 sal_uLong nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
153 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(maViewSize.Width()));
154 sal_uLong nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
155 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(maViewSize.Height()));
156
157 // Decide whether to take the larger or the smaller factor.
158 sal_uLong nFact = std::min(nX, nY);
159
160 // The factor is transformed according to the current zoom factor.
161 nFact = nFact * nZoom / ZOOM_MULTIPLICATOR10000;
162 mnMinZoom = std::max(sal_uInt16(MIN_ZOOM5), static_cast<sal_uInt16>(nFact));
163
164 // If the current zoom factor is smaller than the calculated minimal
165 // zoom factor then set the new minimal factor as the current zoom
166 // factor.
167 if ( nZoom < static_cast<long>(mnMinZoom) )
168 SetZoomFactor(mnMinZoom);
169}
170
171void Window::SetMinZoom (long int nMin)
172{
173 mnMinZoom = static_cast<sal_uInt16>(nMin);
174}
175
176void Window::SetMaxZoom (long int nMax)
177{
178 mnMaxZoom = static_cast<sal_uInt16>(nMax);
179}
180
181long Window::GetZoom() const
182{
183 if( GetMapMode().GetScaleX().GetDenominator() )
184 {
185 return long(GetMapMode().GetScaleX() * 100);
186 }
187 else
188 {
189 return 0;
190 }
191}
192
193void Window::Resize()
194{
195 vcl::Window::Resize();
196 CalcMinZoom();
197
198 if( mpViewShell && mpViewShell->GetViewFrame() )
199 mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) );
200}
201
202void Window::PrePaint(vcl::RenderContext& /*rRenderContext*/)
203{
204 if ( mpViewShell )
205 mpViewShell->PrePaint();
206}
207
208void Window::Paint(vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect)
209{
210 if ( mpViewShell )
211 mpViewShell->Paint(rRect, this);
212}
213
214void Window::KeyInput(const KeyEvent& rKEvt)
215{
216 if (getenv("SD_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 && mpViewShell)
217 {
218 mpViewShell->GetDoc()->dumpAsXml(nullptr);
219 OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
220 if (pOLV)
221 pOLV->GetEditView().GetEditEngine()->dumpAsXmlEditDoc(nullptr);
222 return;
223 }
224
225 if (!(mpViewShell && mpViewShell->KeyInput(rKEvt, this)))
226 {
227 if (mpViewShell && rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
228 {
229 mpViewShell->GetViewShell()->Escape();
230 }
231 else
232 {
233 vcl::Window::KeyInput(rKEvt);
234 }
235 }
236}
237
238void Window::MouseButtonDown(const MouseEvent& rMEvt)
239{
240 if ( mpViewShell )
241 mpViewShell->MouseButtonDown(rMEvt, this);
242}
243
244void Window::MouseMove(const MouseEvent& rMEvt)
245{
246 if ( mpViewShell )
247 mpViewShell->MouseMove(rMEvt, this);
248}
249
250void Window::MouseButtonUp(const MouseEvent& rMEvt)
251{
252 mnTicks = 0;
253
254 if ( mpViewShell )
255 mpViewShell->MouseButtonUp(rMEvt, this);
256}
257
258void Window::Command(const CommandEvent& rCEvt)
259{
260 if (mpViewShell)
261 mpViewShell->Command(rCEvt, this);
262 //pass at least alt press/release to parent impl
263 if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
264 vcl::Window::Command(rCEvt);
265 //show the text edit outliner view cursor
266 else if (!HasFocus() && rCEvt.GetCommand() == CommandEventId::CursorPos)
267 {
268 OutlinerView* pOLV = mpViewShell ? mpViewShell->GetView()->GetTextEditOutlinerView() : nullptr;
269 if (pOLV && this == pOLV->GetWindow())
270 {
271 GrabFocus();
272 pOLV->ShowCursor();
273 }
274 }
275}
276
277bool Window::EventNotify( NotifyEvent& rNEvt )
278{
279 bool bResult = false;
280 if ( mpViewShell )
281 {
282 bResult = mpViewShell->Notify(rNEvt, this);
283 }
284 if( !bResult )
285 bResult = vcl::Window::EventNotify(rNEvt);
286
287 return bResult;
288}
289
290void Window::RequestHelp(const HelpEvent& rEvt)
291{
292 if (!mpViewShell || !mpViewShell->RequestHelp(rEvt))
293 vcl::Window::RequestHelp( rEvt );
294}
295
296/**
297 * Set the position of the upper left corner from the visible area of the
298 * window.
299 */
300void Window::SetWinViewPos(const Point& rPnt)
301{
302 maWinPos = rPnt;
303}
304
305/**
306 * Set origin of the representation in respect to the whole working area.
307 */
308void Window::SetViewOrigin(const Point& rPnt)
309{
310 maViewOrigin = rPnt;
311}
312
313/**
314 * Set size of the whole working area which can be seen with the window.
315 */
316void Window::SetViewSize(const Size& rSize)
317{
318 maViewSize = rSize;
319 CalcMinZoom();
320}
321
322void Window::SetCenterAllowed (bool bIsAllowed)
323{
324 mbCenterAllowed = bIsAllowed;
325}
326
327long Window::SetZoomFactor(long nZoom)
328{
329 // Clip the zoom factor to the valid range marked by nMinZoom as
330 // calculated by CalcMinZoom() and the constant MAX_ZOOM.
331 if ( nZoom > MAX_ZOOM3000 )
332 nZoom = MAX_ZOOM3000;
333 if ( nZoom < static_cast<long>(mnMinZoom) )
334 nZoom = mnMinZoom;
335
336 // Set the zoom factor at the window's map mode.
337 if (!comphelper::LibreOfficeKit::isActive())
338 {
339 MapMode aMap(GetMapMode());
340 aMap.SetScaleX(Fraction(nZoom, 100));
341 aMap.SetScaleY(Fraction(nZoom, 100));
342 SetMapMode(aMap);
343 }
344
345 // invalidate previous size - it was relative to the old scaling
346 maPrevSize = Size(-1,-1);
347
348 // Update the map mode's origin (to what effect?).
349 UpdateMapOrigin();
350
351 // Update the view's snapping to the new zoom factor.
352 if ( auto pDrawViewShell = dynamic_cast< DrawViewShell *>( mpViewShell ) )
353 pDrawViewShell->GetView()->RecalcLogicSnapMagnetic(*this);
354
355 // Return the zoom factor just in case it has been changed above to lie
356 // inside the valid range.
357 return nZoom;
358}
359
360void Window::SetZoomIntegral(long nZoom)
361{
362 // Clip the zoom factor to the valid range marked by nMinZoom as
363 // previously calculated by <member>CalcMinZoom()</member> and the
364 // MAX_ZOOM constant.
365 if ( nZoom > MAX_ZOOM3000 )
366 nZoom = MAX_ZOOM3000;
367 if ( nZoom < static_cast<long>(mnMinZoom) )
368 nZoom = mnMinZoom;
369
370 // Calculate the window's new origin.
371 Size aSize = PixelToLogic(GetOutputSizePixel());
372 long nW = aSize.Width() * GetZoom() / nZoom;
373 long nH = aSize.Height() * GetZoom() / nZoom;
374 maWinPos.AdjustX((aSize.Width() - nW) / 2 );
375 maWinPos.AdjustY((aSize.Height() - nH) / 2 );
376 if ( maWinPos.X() < 0 ) maWinPos.setX( 0 );
377 if ( maWinPos.Y() < 0 ) maWinPos.setY( 0 );
378
379 // Finally update this window's map mode to the given zoom factor that
380 // has been clipped to the valid range.
381 SetZoomFactor(nZoom);
382}
383
384long Window::GetZoomForRect( const ::tools::Rectangle& rZoomRect )
385{
386 long nRetZoom = 100;
387
388 if( (rZoomRect.GetWidth() != 0) && (rZoomRect.GetHeight() != 0))
389 {
390 // Calculate the scale factors which will lead to the given
391 // rectangle being fully visible (when translated accordingly) as
392 // large as possible in the output area independently in both
393 // coordinate directions .
394 sal_uLong nX(0);
395 sal_uLong nY(0);
396
397 const Size aWinSize( PixelToLogic(GetOutputSizePixel()) );
398 if(rZoomRect.GetHeight())
399 {
400 nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
401 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(rZoomRect.GetHeight()));
402 }
403
404 if(rZoomRect.GetWidth())
405 {
406 nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
407 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(rZoomRect.GetWidth()));
408 }
409
410 // Use the smaller one of both so that the zoom rectangle will be
411 // fully visible with respect to both coordinate directions.
412 sal_uLong nFact = std::min(nX, nY);
413
414 // Transform the current zoom factor so that it leads to the desired
415 // scaling.
416 nRetZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR10000;
417
418 // Calculate the new origin.
419 if ( nFact == 0 )
420 {
421 // Don't change anything if the scale factor is degenerate.
422 nRetZoom = GetZoom();
423 }
424 else
425 {
426 // Clip the zoom factor to the valid range marked by nMinZoom as
427 // previously calculated by <member>CalcMinZoom()</member> and the
428 // MAX_ZOOM constant.
429 if ( nRetZoom > MAX_ZOOM3000 )
430 nRetZoom = MAX_ZOOM3000;
431 if ( nRetZoom < static_cast<long>(mnMinZoom) )
432 nRetZoom = mnMinZoom;
433 }
434 }
435
436 return nRetZoom;
437}
438
439/** Recalculate the zoom factor and translation so that the given rectangle
440 is displayed centered and as large as possible while still being fully
441 visible in the window.
442*/
443long Window::SetZoomRect (const ::tools::Rectangle& rZoomRect)
444{
445 long nNewZoom = 100;
446
447 if (rZoomRect.GetWidth() == 0 || rZoomRect.GetHeight() == 0)
448 {
449 // The given rectangle is degenerate. Use the default zoom factor
450 // (above) of 100%.
451 SetZoomIntegral(nNewZoom);
452 }
453 else
454 {
455 Point aPos = rZoomRect.TopLeft();
456 // Transform the output area from pixel coordinates into logical
457 // coordinates.
458 Size aWinSize = PixelToLogic(GetOutputSizePixel());
459 // Paranoia! The degenerate case of zero width or height has been
460 // taken care of above.
461 DBG_ASSERT(rZoomRect.GetWidth(), "ZoomRect-Width = 0!")do { if (true && (!(rZoomRect.GetWidth()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "461" ": "), "%s", "ZoomRect-Width = 0!"); } } while (false
)
;
462 DBG_ASSERT(rZoomRect.GetHeight(), "ZoomRect-Height = 0!")do { if (true && (!(rZoomRect.GetHeight()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "462" ": "), "%s", "ZoomRect-Height = 0!"); } } while (false
)
;
463
464 // Calculate the scale factors which will lead to the given
465 // rectangle being fully visible (when translated accordingly) as
466 // large as possible in the output area independently in both
467 // coordinate directions .
468 sal_uLong nX(0);
469 sal_uLong nY(0);
470
471 if(rZoomRect.GetHeight())
472 {
473 nX = static_cast<sal_uLong>(static_cast<double>(aWinSize.Height())
474 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(rZoomRect.GetHeight()));
475 }
476
477 if(rZoomRect.GetWidth())
478 {
479 nY = static_cast<sal_uLong>(static_cast<double>(aWinSize.Width())
480 * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(rZoomRect.GetWidth()));
481 }
482
483 // Use the smaller one of both so that the zoom rectangle will be
484 // fully visible with respect to both coordinate directions.
485 sal_uLong nFact = std::min(nX, nY);
486
487 // Transform the current zoom factor so that it leads to the desired
488 // scaling.
489 long nZoom = nFact * GetZoom() / ZOOM_MULTIPLICATOR10000;
490
491 // Calculate the new origin.
492 if ( nFact == 0 )
493 {
494 // Don't change anything if the scale factor is degenerate.
495 nNewZoom = GetZoom();
496 }
497 else
498 {
499 // Calculate the new window position that centers the given
500 // rectangle on the screen.
501 if ( nZoom > MAX_ZOOM3000 )
502 nFact = nFact * MAX_ZOOM3000 / nZoom;
503
504 maWinPos = maViewOrigin + aPos;
505
506 aWinSize.setWidth( static_cast<long>(static_cast<double>(aWinSize.Width()) * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(nFact)) );
507 maWinPos.AdjustX((rZoomRect.GetWidth() - aWinSize.Width()) / 2 );
508 aWinSize.setHeight( static_cast<long>(static_cast<double>(aWinSize.Height()) * double(ZOOM_MULTIPLICATOR10000) / static_cast<double>(nFact)) );
509 maWinPos.AdjustY((rZoomRect.GetHeight() - aWinSize.Height()) / 2 );
510
511 if ( maWinPos.X() < 0 ) maWinPos.setX( 0 );
512 if ( maWinPos.Y() < 0 ) maWinPos.setY( 0 );
513
514 // Adapt the window's map mode to the new zoom factor.
515 nNewZoom = SetZoomFactor(nZoom);
516 }
517 }
518
519 return nNewZoom;
520}
521
522void Window::SetMinZoomAutoCalc (bool bAuto)
523{
524 mbMinZoomAutoCalc = bAuto;
525}
526
527/**
528 * Calculate and set new MapMode origin.
529 * If aWinPos.X()/Y() == -1, then we center the corresponding position (e.g. for
530 * initialization).
531 */
532void Window::UpdateMapOrigin(bool bInvalidate)
533{
534 bool bChanged = false;
535 const Size aWinSize = PixelToLogic(GetOutputSizePixel());
536
537 if ( mbCenterAllowed )
538 {
539 if( maPrevSize != Size(-1,-1) )
540 {
541 // keep view centered around current pos, when window
542 // resizes
543 maWinPos.AdjustX( -((aWinSize.Width() - maPrevSize.Width()) / 2) );
544 maWinPos.AdjustY( -((aWinSize.Height() - maPrevSize.Height()) / 2) );
545 bChanged = true;
546 }
547
548 if ( maWinPos.X() > maViewSize.Width() - aWinSize.Width() )
549 {
550 maWinPos.setX( maViewSize.Width() - aWinSize.Width() );
551 bChanged = true;
552 }
553 if ( maWinPos.Y() > maViewSize.Height() - aWinSize.Height() )
554 {
555 maWinPos.setY( maViewSize.Height() - aWinSize.Height() );
556 bChanged = true;
557 }
558 if ( aWinSize.Width() > maViewSize.Width() || maWinPos.X() < 0 )
559 {
560 maWinPos.setX( maViewSize.Width() / 2 - aWinSize.Width() / 2 );
561 bChanged = true;
562 }
563 if ( aWinSize.Height() > maViewSize.Height() || maWinPos.Y() < 0 )
564 {
565 maWinPos.setY( maViewSize.Height() / 2 - aWinSize.Height() / 2 );
566 bChanged = true;
567 }
568 }
569
570 UpdateMapMode ();
571
572 maPrevSize = aWinSize;
573
574 // When tiled rendering, the above UpdateMapMode() call doesn't touch the map mode.
575 if (bChanged && bInvalidate && !comphelper::LibreOfficeKit::isActive())
576 Invalidate();
577}
578
579void Window::UpdateMapMode()
580{
581 maWinPos -= maViewOrigin;
582 Size aPix(maWinPos.X(), maWinPos.Y());
583 aPix = LogicToPixel(aPix);
584 // Size has to be a multiple of BRUSH_SIZE due to the correct depiction of
585 // pattern
586 // #i2237#
587 // removed old stuff here which still forced zoom to be
588 // %BRUSH_SIZE which is outdated now
589
590 if (dynamic_cast< DrawViewShell *>( mpViewShell ))
591 {
592 // page should not "stick" to the window border
593 if (aPix.Width() == 0)
594 {
595 // #i2237#
596 // Since BRUSH_SIZE alignment is outdated now, i use the
597 // former constant here directly
598 aPix.AdjustWidth( -8 );
599 }
600 if (aPix.Height() == 0)
601 {
602 // #i2237#
603 // Since BRUSH_SIZE alignment is outdated now, i use the
604 // former constant here directly
605 aPix.AdjustHeight( -8 );
606 }
607 }
608
609 aPix = PixelToLogic(aPix);
610 maWinPos.setX( aPix.Width() );
611 maWinPos.setY( aPix.Height() );
612 Point aNewOrigin (-maWinPos.X(), -maWinPos.Y());
613 maWinPos += maViewOrigin;
614
615 if (!comphelper::LibreOfficeKit::isActive())
616 {
617 MapMode aMap(GetMapMode());
618 aMap.SetOrigin(aNewOrigin);
619 SetMapMode(aMap);
620 }
621}
622
623/**
624 * @returns X position of the visible area as fraction (< 1) of the whole
625 * working area.
626 */
627double Window::GetVisibleX() const
628{
629 return (static_cast<double>(maWinPos.X()) / maViewSize.Width());
630}
631
632/**
633 * @returns Y position of the visible area as fraction (< 1) of the whole
634 * working area.
635 */
636double Window::GetVisibleY() const
637{
638 return (static_cast<double>(maWinPos.Y()) / maViewSize.Height());
639}
640
641/**
642 * Set x and y position of the visible area as fraction (< 1) of the whole
643 * working area. Negative values are ignored.
644 */
645void Window::SetVisibleXY(double fX, double fY)
646{
647 long nOldX = maWinPos.X();
648 long nOldY = maWinPos.Y();
649
650 if ( fX >= 0 )
651 maWinPos.setX( static_cast<long>(fX * maViewSize.Width()) );
652 if ( fY >= 0 )
653 maWinPos.setY( static_cast<long>(fY * maViewSize.Height()) );
654 UpdateMapOrigin(false);
655 Scroll(nOldX - maWinPos.X(), nOldY - maWinPos.Y(), ScrollFlags::Children);
656 PaintImmediately();
657}
658
659/**
660 * @returns width of the visible area in proportion to the width of the whole
661 * working area.
662 */
663double Window::GetVisibleWidth() const
664{
665 Size aWinSize = PixelToLogic(GetOutputSizePixel());
666 if ( aWinSize.Width() > maViewSize.Width() )
667 aWinSize.setWidth( maViewSize.Width() );
668 return (static_cast<double>(aWinSize.Width()) / maViewSize.Width());
669}
670
671/**
672 * @returns height of the visible area in proportion to the height of the whole
673 * working area.
674 */
675double Window::GetVisibleHeight() const
676{
677 Size aWinSize = PixelToLogic(GetOutputSizePixel());
678 if ( aWinSize.Height() > maViewSize.Height() )
679 aWinSize.setHeight( maViewSize.Height() );
680 return (static_cast<double>(aWinSize.Height()) / maViewSize.Height());
681}
682
683Point Window::GetVisibleCenter()
684{
685 Point aPos = ::tools::Rectangle(Point(), GetOutputSizePixel()).Center();
686
687 // For LOK
688 bool bMapModeWasEnabled(IsMapModeEnabled());
689 EnableMapMode(/*true*/);
690 aPos = PixelToLogic(aPos);
691 EnableMapMode(bMapModeWasEnabled);
692
693 return aPos;
694}
695
696/**
697 * @returns width of a scroll column in proportion to the width of the whole
698 * working area.
699 */
700double Window::GetScrlLineWidth() const
701{
702 return (GetVisibleWidth() * SCROLL_LINE_FACT0.05);
703}
704
705/**
706 * @returns height of a scroll column in proportion to the height of the whole
707 * working area.
708 */
709double Window::GetScrlLineHeight() const
710{
711 return (GetVisibleHeight() * SCROLL_LINE_FACT0.05);
712}
713
714/**
715 * @returns width of a scroll page in proportion to the width of the whole
716 * working area.
717 */
718double Window::GetScrlPageWidth() const
719{
720 return (GetVisibleWidth() * SCROLL_PAGE_FACT0.5);
721}
722
723/**
724 * @returns height of a scroll page in proportion to the height of the whole
725 * working area.
726 */
727double Window::GetScrlPageHeight() const
728{
729 return (GetVisibleHeight() * SCROLL_PAGE_FACT0.5);
730}
731
732/**
733 * Deactivate window.
734 */
735void Window::LoseFocus()
736{
737 mnTicks = 0;
738 vcl::Window::LoseFocus ();
739}
740
741/**
742 * Activate window.
743 */
744void Window::GrabFocus()
745{
746 mnTicks = 0;
747 vcl::Window::GrabFocus ();
748}
749
750void Window::DataChanged( const DataChangedEvent& rDCEvt )
751{
752 vcl::Window::DataChanged( rDCEvt );
753
754 /* Omit PRINTER by all documents which are not using a printer.
755 Omit FONTS and FONTSUBSTITUTION if no text output is available or if the
756 document does not allow text. */
757
758 if ( !((rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
1
Assuming the condition is false
6
Taking false branch
759 (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
2
Assuming the condition is false
760 (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
3
Assuming the condition is false
761 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
4
Assuming the condition is false
762 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
5
Assuming the condition is true
763 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))) )
764 return;
765
766 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
7
Taking true branch
767 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
768 {
769 /* Rearrange or initiate Resize for scroll bars since the size of
770 the scroll bars my have changed. Within this, inside the resize-
771 handler, the size of the scroll bars will be asked from the
772 Settings. */
773 Resize();
774
775 /* Re-set data, which are from system control or from Settings. May
776 have to re-set more data since the resolution may also has
777 changed. */
778 if( mpViewShell )
8
Assuming field 'mpViewShell' is non-null
9
Taking true branch
779 {
780 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
781 SvtAccessibilityOptions aAccOptions;
782 DrawModeFlags nOutputMode;
783 sal_uInt16 nPreviewSlot;
784
785 if( rStyleSettings.GetHighContrastMode() )
10
Assuming the condition is false
11
Taking false branch
786 nOutputMode = sd::OUTPUT_DRAWMODE_CONTRAST;
787 else
788 nOutputMode = sd::OUTPUT_DRAWMODE_COLOR;
789
790 if( rStyleSettings.GetHighContrastMode() && aAccOptions.GetIsForPagePreviews() )
12
Assuming the condition is false
791 nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST(27000 +401);
792 else
793 nPreviewSlot = SID_PREVIEW_QUALITY_COLOR(27000 +369);
794
795 if( dynamic_cast< DrawViewShell *>( mpViewShell ) != nullptr )
13
Taking true branch
796 {
797 SetDrawMode( nOutputMode );
798 mpViewShell->GetFrameView()->SetDrawMode( nOutputMode );
799 Invalidate();
14
Value assigned to field 'mpViewShell'
800 }
801
802 // Overwrite window color for OutlineView
803 if( dynamic_cast< OutlineViewShell *>( mpViewShell ) != nullptr )
15
Assuming pointer value is null
16
Taking false branch
804 {
805 svtools::ColorConfig aColorConfig;
806 const Color aDocColor( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
807 SetBackground( Wallpaper( aDocColor ) );
808 }
809
810 SfxRequest aReq( nPreviewSlot, SfxCallMode::SLOT, mpViewShell->GetDocSh()->GetDoc()->GetItemPool() );
17
Called C++ object pointer is null
811 mpViewShell->ExecReq( aReq );
812 mpViewShell->Invalidate();
813 mpViewShell->ArrangeGUIElements();
814
815 // re-create handles to show new outfit
816 if(dynamic_cast< DrawViewShell *>( mpViewShell ) != nullptr)
817 {
818 mpViewShell->GetView()->AdjustMarkHdl();
819 }
820 }
821 }
822
823 if ( (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
824 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
825 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
826 {
827 /* Virtual devices, which also depends on the resolution or the
828 system control, should be updated. Otherwise, we should update
829 the virtual devices at least at DataChangedEventType::DISPLAY since some
830 systems allow to change the resolution and color depth during
831 runtime. Or the virtual devices have to be updated when the color
832 palette has changed since a different color matching can be used
833 when outputting. */
834 }
835
836 if ( rDCEvt.GetType() == DataChangedEventType::FONTS )
837 {
838 /* If the document provides font choose boxes, we have to update
839 them. I don't know how this looks like (also not really me, I
840 only translated the comment ;). We may can handle it global. We
841 have to discuss it with PB, but he is ill at the moment.
842 Before we handle it here, discuss it with PB and me. */
843 }
844
845 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
846 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) )
847 {
848 /* Do reformatting since the fonts of the document may no longer
849 exist, or exist now, or are replaced with others. */
850 if( mpViewShell )
851 {
852 DrawDocShell* pDocSh = mpViewShell->GetDocSh();
853 if( pDocSh )
854 pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
855 }
856 }
857
858 if ( rDCEvt.GetType() == DataChangedEventType::PRINTER )
859 {
860 /* I don't know how the handling should look like. Maybe we delete a
861 printer and look what we have to do. Maybe I have to add
862 something to the VCL, in case the used printer is deleted.
863 Otherwise I may recalculate the formatting here if the current
864 printer is destroyed. */
865 if( mpViewShell )
866 {
867 DrawDocShell* pDocSh = mpViewShell->GetDocSh();
868 if( pDocSh )
869 pDocSh->SetPrinter( pDocSh->GetPrinter( true ) );
870 }
871 }
872
873 // Update everything
874 Invalidate();
875}
876
877sal_Int8 Window::AcceptDrop( const AcceptDropEvent& rEvt )
878{
879 sal_Int8 nRet = DND_ACTION_NONEcss::datatransfer::dnd::DNDConstants::ACTION_NONE;
880
881 if( mpViewShell && !mpViewShell->GetDocSh()->IsReadOnly() )
882 {
883 nRet = mpViewShell->AcceptDrop( rEvt, *this, this, SDRPAGE_NOTFOUND0xFFFF, SDRLAYER_NOTFOUND );
884
885 if (mbUseDropScroll && dynamic_cast< OutlineViewShell *>( mpViewShell ) == nullptr)
886 DropScroll( rEvt.maPosPixel );
887 }
888
889 return nRet;
890}
891
892sal_Int8 Window::ExecuteDrop( const ExecuteDropEvent& rEvt )
893{
894 sal_Int8 nRet = DND_ACTION_NONEcss::datatransfer::dnd::DNDConstants::ACTION_NONE;
895
896 if( mpViewShell )
897 {
898 nRet = mpViewShell->ExecuteDrop( rEvt, *this, this, SDRPAGE_NOTFOUND0xFFFF, SDRLAYER_NOTFOUND );
899 }
900
901 return nRet;
902}
903
904void Window::SetUseDropScroll (bool bUseDropScroll)
905{
906 mbUseDropScroll = bUseDropScroll;
907}
908
909void Window::DropScroll(const Point& rMousePos)
910{
911 short nDx = 0;
912 short nDy = 0;
913
914 Size aSize = GetOutputSizePixel();
915
916 if (aSize.Width() > SCROLL_SENSITIVE20 * 3)
917 {
918 if ( rMousePos.X() < SCROLL_SENSITIVE20 )
919 {
920 nDx = -1;
921 }
922
923 if ( rMousePos.X() >= aSize.Width() - SCROLL_SENSITIVE20 )
924 {
925 nDx = 1;
926 }
927 }
928
929 if (aSize.Height() > SCROLL_SENSITIVE20 * 3)
930 {
931 if ( rMousePos.Y() < SCROLL_SENSITIVE20 )
932 {
933 nDy = -1;
934 }
935
936 if ( rMousePos.Y() >= aSize.Height() - SCROLL_SENSITIVE20 )
937 {
938 nDy = 1;
939 }
940 }
941
942 if ( (nDx || nDy) && (rMousePos.X()!=0 || rMousePos.Y()!=0 ) )
943 {
944 if (mnTicks > 20)
945 mpViewShell->ScrollLines(nDx, nDy);
946 else
947 mnTicks ++;
948 }
949}
950
951css::uno::Reference<css::accessibility::XAccessible>
952 Window::CreateAccessible()
953{
954 // If current viewshell is PresentationViewShell, just return empty because the correct ShowWin will be created later.
955 if (dynamic_cast< PresentationViewShell *>( mpViewShell ))
956 {
957 return vcl::Window::CreateAccessible ();
958 }
959 css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible(false);
960 if (xAcc)
961 {
962 return xAcc;
963 }
964 if (mpViewShell != nullptr)
965 {
966 xAcc = mpViewShell->CreateAccessibleDocumentView (this);
967 SetAccessible(xAcc);
968 return xAcc;
969 }
970 else
971 {
972 SAL_WARN("sd", "::sd::Window::CreateAccessible: no view shell")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sd")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "::sd::Window::CreateAccessible: no view shell") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd")
, ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "972" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "::sd::Window::CreateAccessible: no view shell"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "::sd::Window::CreateAccessible: no view shell"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "972" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "::sd::Window::CreateAccessible: no view shell") ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd")
, ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "972" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "::sd::Window::CreateAccessible: no view shell"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "::sd::Window::CreateAccessible: no view shell"; ::
sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
":" "972" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
973 return vcl::Window::CreateAccessible ();
974 }
975}
976
977OUString Window::GetSurroundingText() const
978{
979 if ( mpViewShell->GetShellType() == ViewShell::ST_OUTLINE )
980 return OUString();
981 else if ( mpViewShell->GetView()->IsTextEdit() )
982 {
983 OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
984 return pOLV->GetEditView().GetSurroundingText();
985 }
986 return OUString();
987}
988
989Selection Window::GetSurroundingTextSelection() const
990{
991 if ( mpViewShell->GetShellType() == ViewShell::ST_OUTLINE )
992 {
993 return Selection( 0, 0 );
994 }
995 else if ( mpViewShell->GetView()->IsTextEdit() )
996 {
997 OutlinerView *pOLV = mpViewShell->GetView()->GetTextEditOutlinerView();
998 return pOLV->GetEditView().GetSurroundingTextSelection();
999 }
1000 else
1001 {
1002 return Selection( 0, 0 );
1003 }
1004}
1005
1006void Window::LogicInvalidate(const ::tools::Rectangle* pRectangle)
1007{
1008 DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell);
1009 if (!pDrawViewShell || pDrawViewShell->IsInSwitchPage())
1010 return;
1011
1012 if (!comphelper::LibreOfficeKit::isActive())
1013 return;
1014 OString sRectangle;
1015 if (!pRectangle)
1016 sRectangle = "EMPTY";
1017 else
1018 {
1019 ::tools::Rectangle aRectangle(*pRectangle);
1020 if (GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
1021 aRectangle = OutputDevice::LogicToLogic(aRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
1022 sRectangle = aRectangle.toString();
1023 }
1024 SfxViewShell& rSfxViewShell = pDrawViewShell->GetViewShellBase();
1025 SfxLokHelper::notifyInvalidation(&rSfxViewShell, sRectangle);
1026}
1027
1028void Window::LogicMouseButtonDown(const MouseEvent& rMouseEvent)
1029{
1030 // When we're not doing tiled rendering, then positions must be passed as pixels.
1031 assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive
()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()"
, "/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
, 1031, __extension__ __PRETTY_FUNCTION__))
;
1032
1033 Point aPoint = GetPointerPosPixel();
1034 SetLastMousePos(rMouseEvent.GetPosPixel());
1035
1036 mpViewShell->MouseButtonDown(rMouseEvent, this);
1037
1038 SetPointerPosPixel(aPoint);
1039}
1040
1041void Window::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
1042{
1043 // When we're not doing tiled rendering, then positions must be passed as pixels.
1044 assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive
()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()"
, "/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
, 1044, __extension__ __PRETTY_FUNCTION__))
;
1045
1046 Point aPoint = GetPointerPosPixel();
1047 SetLastMousePos(rMouseEvent.GetPosPixel());
1048
1049 mpViewShell->MouseButtonUp(rMouseEvent, this);
1050
1051 SetPointerPosPixel(aPoint);
1052}
1053
1054void Window::LogicMouseMove(const MouseEvent& rMouseEvent)
1055{
1056 // When we're not doing tiled rendering, then positions must be passed as pixels.
1057 assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive
()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()"
, "/home/maarten/src/libreoffice/core/sd/source/ui/view/sdwindow.cxx"
, 1057, __extension__ __PRETTY_FUNCTION__))
;
1058
1059 Point aPoint = GetPointerPosPixel();
1060 SetLastMousePos(rMouseEvent.GetPosPixel());
1061
1062 mpViewShell->MouseMove(rMouseEvent, this);
1063
1064 SetPointerPosPixel(aPoint);
1065}
1066
1067FactoryFunction Window::GetUITestFactory() const
1068{
1069 if (get_id() == "impress_win")
1070 return ImpressWindowUIObject::create;
1071
1072 return WindowUIObject::create;
1073}
1074
1075} // end of namespace sd
1076
1077/* vim:set shiftwidth=4 softtabstop=4 expandtab: */