Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 192, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pview.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx

/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.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 <sfx2/objface.hxx>
21#include <vcl/help.hxx>
22#include <vcl/commandevent.hxx>
23#include <vcl/settings.hxx>
24#include <vcl/svapp.hxx>
25#include <vcl/syswin.hxx>
26#include <vcl/weld.hxx>
27
28#include <rtl/ustrbuf.hxx>
29#include <svl/whiter.hxx>
30#include <svl/stritem.hxx>
31#include <svl/eitem.hxx>
32#include <sfx2/printer.hxx>
33#include <sfx2/bindings.hxx>
34#include <sfx2/request.hxx>
35#include <sfx2/dispatch.hxx>
36#include <editeng/paperinf.hxx>
37#include <svx/svdview.hxx>
38#include <svx/zoomslideritem.hxx>
39#include <tools/svborder.hxx>
40
41#include <globdoc.hxx>
42#include <wdocsh.hxx>
43#include <pvprtdat.hxx>
44#include <swmodule.hxx>
45#include <wrtsh.hxx>
46#include <docsh.hxx>
47#include <viewopt.hxx>
48#include <doc.hxx>
49#include <IDocumentDeviceAccess.hxx>
50#include <pview.hxx>
51#include <view.hxx>
52#include <scroll.hxx>
53#include <prtopt.hxx>
54#include <usrpref.hxx>
55#include "viewfunc.hxx"
56
57#include <helpids.h>
58#include <cmdid.h>
59#include <strings.hrc>
60
61#define ShellClass_SwPagePreview
62#include <sfx2/msg.hxx>
63#include <swslots.hxx>
64#include <pagepreviewlayout.hxx>
65
66#include <svx/svxdlg.hxx>
67
68#include <memory>
69#include <vcl/EnumContext.hxx>
70#include <vcl/notebookbar.hxx>
71
72using namespace ::com::sun::star;
73SFX_IMPL_NAMED_VIEWFACTORY(SwPagePreview, "PrintPreview")SfxViewFactory* SwPagePreview::pFactory; SfxViewShell* SwPagePreview
::CreateInstance(SfxViewFrame *pFrame, SfxViewShell *pOldView
) { return new SwPagePreview(pFrame, pOldView); } void SwPagePreview
::RegisterFactory( SfxInterfaceId nPrio ) { pFactory = new SfxViewFactory
(&CreateInstance,nPrio,"PrintPreview"); InitFactory(); } void
SwPagePreview::InitFactory()
74{
75 SFX_VIEW_REGISTRATION(SwDocShell)SwDocShell::Factory().RegisterViewFactory( *Factory() );
76 SFX_VIEW_REGISTRATION(SwWebDocShell)SwWebDocShell::Factory().RegisterViewFactory( *Factory() );
77 SFX_VIEW_REGISTRATION(SwGlobalDocShell)SwGlobalDocShell::Factory().RegisterViewFactory( *Factory() );
78}
79
80SFX_IMPL_INTERFACE(SwPagePreview, SfxViewShell)SfxInterface* SwPagePreview::pInterface = nullptr; SfxInterface
* SwPagePreview::GetStaticInterface() { if ( !pInterface ) { pInterface
= new SfxInterface( "SwPagePreview", false, GetInterfaceId()
, SfxViewShell::GetStaticInterface(), aSwPagePreviewSlots_Impl
[0], sal_uInt16(sizeof(aSwPagePreviewSlots_Impl) / sizeof(SfxSlot
) ) ); InitInterface_Impl(); } return pInterface; } SfxInterface
* SwPagePreview::GetInterface() const { return GetStaticInterface
(); } void SwPagePreview::RegisterInterface(const SfxModule* pMod
) { GetStaticInterface()->Register(pMod); }
81
82void SwPagePreview::InitInterface_Impl()
83{
84 GetStaticInterface()->RegisterPopupMenu("preview");
85 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT1,
86 SfxVisibilityFlags::Standard|SfxVisibilityFlags::Client|SfxVisibilityFlags::FullScreen|SfxVisibilityFlags::ReadonlyDoc,
87 ToolbarId::PView_Toolbox);
88}
89
90
91#define SWVIEWFLAGSSfxViewShellFlags::HAS_PRINTOPTIONS SfxViewShellFlags::HAS_PRINTOPTIONS
92
93#define MIN_PREVIEW_ZOOM25 25
94#define MAX_PREVIEW_ZOOM600 600
95
96static sal_uInt16 lcl_GetNextZoomStep(sal_uInt16 nCurrentZoom, bool bZoomIn)
97{
98 static const sal_uInt16 aZoomArr[] =
99 {
100 25, 50, 75, 100, 150, 200, 400, 600
101 };
102 const int nZoomArrSize = static_cast<int>(SAL_N_ELEMENTS(aZoomArr)(sizeof(sal_n_array_size(aZoomArr))));
103 if (bZoomIn)
104 {
105 for(int i = nZoomArrSize - 1; i >= 0; --i)
106 {
107 if(nCurrentZoom > aZoomArr[i] || !i)
108 return aZoomArr[i];
109 }
110 }
111 else
112 {
113 for(sal_uInt16 i : aZoomArr)
114 {
115 if(nCurrentZoom < i)
116 return i;
117 }
118 }
119 return bZoomIn ? MAX_PREVIEW_ZOOM600 : MIN_PREVIEW_ZOOM25;
120};
121
122static void lcl_InvalidateZoomSlots(SfxBindings& rBindings)
123{
124 static sal_uInt16 const aInval[] =
125 {
126 SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ZOOM_OUT(10000 + 97), SID_ZOOM_IN(10000 + 98), SID_ATTR_ZOOMSLIDER( 10000 + 1065 ), FN_PREVIEW_ZOOM((20000 + 200) + 51), FN_STAT_ZOOM((20000 + 1180) + 3),
127 0
128 };
129 rBindings.Invalidate( aInval );
130}
131
132namespace {
133
134// At first the zoom dialog
135class SwPreviewZoomDlg : public weld::GenericDialogController
136{
137 SwPagePreviewWin& m_rParent;
138 std::unique_ptr<weld::SpinButton> m_xRowEdit;
139 std::unique_ptr<weld::SpinButton> m_xColEdit;
140
141public:
142 SwPreviewZoomDlg(SwPagePreviewWin& rParent)
143 : GenericDialogController(rParent.GetFrameWeld(), "modules/swriter/ui/previewzoomdialog.ui", "PreviewZoomDialog")
144 , m_rParent(rParent)
145 , m_xRowEdit(m_xBuilder->weld_spin_button("rows"))
146 , m_xColEdit(m_xBuilder->weld_spin_button("cols"))
147 {
148 m_xRowEdit->set_value(rParent.GetRow());
149 m_xColEdit->set_value(rParent.GetCol());
150 }
151
152 void execute()
153 {
154 if (run() == RET_OK)
155 {
156 m_rParent.CalcWish(sal_uInt8(m_xRowEdit->get_value()), sal_uInt8(m_xColEdit->get_value()));
157 }
158 }
159};
160
161}
162
163// all for SwPagePreviewWin
164SwPagePreviewWin::SwPagePreviewWin( vcl::Window *pParent, SwPagePreview& rPView )
165 : Window(pParent, WinBits(WB_CLIPCHILDREN))
166 , mpViewShell(nullptr)
167 , mrView(rPView)
168 , mbCalcScaleForPreviewLayout(true)
169 , maPaintedPreviewDocRect(tools::Rectangle(0,0,0,0))
170 , mpPgPreviewLayout(nullptr)
171{
172 SetOutDevViewType( OutDevViewType::PrintPreview );
173 SetHelpId(HID_PAGEPREVIEW"SW_HID_PAGEPREVIEW");
174 SetFillColor( GetBackground().GetColor() );
175 SetLineColor( GetBackground().GetColor());
176 SetMapMode( MapMode(MapUnit::MapTwip) );
177
178 const SwMasterUsrPref *pUsrPref = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetUsrPref(false);
179 mnRow = pUsrPref->GetPagePrevRow(); // 1 row
180 mnCol = pUsrPref->GetPagePrevCol(); // 1 column
181 mnSttPage = USHRT_MAX(32767 *2 +1);
182}
183
184SwPagePreviewWin::~SwPagePreviewWin()
185{
186}
187
188void SwPagePreviewWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
189{
190 if (!mpViewShell || !mpViewShell->GetLayout())
191 return;
192
193 if (USHRT_MAX(32767 *2 +1) == mnSttPage) // was never calculated ? (Init-Phase!)
194 {
195 // This is the size to which I always relate.
196 if (!maPxWinSize.Height() || !maPxWinSize.Width())
197 maPxWinSize = GetOutputSizePixel();
198
199 tools::Rectangle aRect(rRenderContext.LogicToPixel(rRect));
200 mpPgPreviewLayout->Prepare(1, Point(0,0), maPxWinSize,
201 mnSttPage, maPaintedPreviewDocRect);
202 SetSelectedPage(1);
203 mpPgPreviewLayout->Paint(rRenderContext, rRenderContext.PixelToLogic(aRect));
204 SetPagePreview(mnRow, mnCol);
205 }
206 else
207 {
208 MapMode aMM(rRenderContext.GetMapMode());
209 aMM.SetScaleX(maScale);
210 aMM.SetScaleY(maScale);
211 rRenderContext.SetMapMode(aMM);
212 mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(true);
213 mpPgPreviewLayout->Paint(rRenderContext, rRect);
214 mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(false);
215 }
216}
217
218void SwPagePreviewWin::CalcWish( sal_uInt8 nNewRow, sal_uInt8 nNewCol )
219{
220 if( !mpViewShell || !mpViewShell->GetLayout() )
221 return;
222
223 const sal_uInt8 nOldCol = mnCol;
224 mnRow = nNewRow;
225 mnCol = nNewCol;
226 const sal_uInt16 nPages = mnRow * mnCol;
227 const sal_uInt16 nLastSttPg = mrView.GetPageCount()+1 > nPages
228 ? mrView.GetPageCount()+1 - nPages : 0;
229 if( mnSttPage > nLastSttPg )
230 mnSttPage = nLastSttPg;
231
232 mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
233 mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
234 mnSttPage, maPaintedPreviewDocRect );
235 SetSelectedPage( mnSttPage );
236 SetPagePreview(mnRow, mnCol);
237 maScale = GetMapMode().GetScaleX();
238
239 // If changes have taken place at the columns, the special case "single column"
240 // must be considered and corrected if necessary.
241 if( (1 == nOldCol) != (1 == mnCol) )
242 mrView.ScrollDocSzChg();
243
244 // Order must be maintained!
245 // additional invalidate page status.
246 static sal_uInt16 aInval[] =
247 {
248 SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ZOOM_OUT(10000 + 97), SID_ZOOM_IN(10000 + 98),
249 FN_PREVIEW_ZOOM((20000 + 200) + 51),
250 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38),
251 FN_STAT_PAGE((20000 + 1180) + 1), FN_STAT_ZOOM((20000 + 1180) + 3),
252 FN_SHOW_TWO_PAGES((20000 + 1250) + 1), FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2),
253 0
254 };
255 SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings();
256 rBindings.Invalidate( aInval );
257 rBindings.Update( FN_SHOW_TWO_PAGES((20000 + 1250) + 1) );
258 rBindings.Update( FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2) );
259 // adjust scrollbars
260 mrView.ScrollViewSzChg();
261}
262
263// mnSttPage is Absolute
264bool SwPagePreviewWin::MovePage( int eMoveMode )
265{
266 // number of pages up
267 const sal_uInt16 nPages = mnRow * mnCol;
268 sal_uInt16 nNewSttPage = mnSttPage;
269 const sal_uInt16 nPageCount = mrView.GetPageCount();
270 const sal_uInt16 nDefSttPg = GetDefSttPage();
271 bool bPaintPageAtFirstCol = true;
272
273 switch( eMoveMode )
274 {
275 case MV_PAGE_UP:
276 {
277 const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
278 const sal_uInt16 nNewAbsSttPage = nRelSttPage - nPages > 0 ?
279 mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage - nPages ) :
280 nDefSttPg;
281 nNewSttPage = nNewAbsSttPage;
282
283 const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
284 const sal_uInt16 nNewRelSelPage = nRelSelPage - nPages > 0 ?
285 nRelSelPage - nPages :
286 1;
287 SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewRelSelPage ) );
288
289 break;
290 }
291 case MV_PAGE_DOWN:
292 {
293 const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage );
294 const sal_uInt16 nNewAbsSttPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage + nPages );
295 nNewSttPage = std::min(nNewAbsSttPage, nPageCount);
296
297 const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() );
298 const sal_uInt16 nNewAbsSelPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSelPage + nPages );
299 SetSelectedPage( std::min(nNewAbsSelPage, nPageCount) );
300
301 break;
302 }
303 case MV_DOC_STT:
304 nNewSttPage = nDefSttPg;
305 SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewSttPage ? nNewSttPage : 1 ) );
306 break;
307 case MV_DOC_END:
308 // correct calculation of new start page.
309 nNewSttPage = nPageCount;
310 SetSelectedPage( nPageCount );
311 break;
312
313 case MV_SELPAGE:
314 // <nNewSttPage> and <SelectedPage()> are already set.
315 // not start at first column, only if the
316 // complete preview layout columns doesn't fit into window.
317 if ( !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
318 bPaintPageAtFirstCol = false;
319 break;
320 case MV_SCROLL:
321 // check, if paint page at first column
322 // has to be avoided
323 if ( !mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() ||
324 !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() )
325 bPaintPageAtFirstCol = false;
326 break;
327 case MV_NEWWINSIZE:
328 // nothing special to do.
329 break;
330 case MV_CALC:
331 // re-init page preview layout.
332 mpPgPreviewLayout->ReInit();
333
334 // correct calculation of new start page.
335 if( nNewSttPage > nPageCount )
336 nNewSttPage = nPageCount;
337
338 // correct selected page number
339 if( SelectedPage() > nPageCount )
340 SetSelectedPage( nNewSttPage ? nNewSttPage : 1 );
341 }
342
343 mpPgPreviewLayout->Prepare( nNewSttPage, Point(0,0), maPxWinSize,
344 nNewSttPage,
345 maPaintedPreviewDocRect, bPaintPageAtFirstCol );
346 if( nNewSttPage == mnSttPage &&
347 eMoveMode != MV_SELPAGE )
348 return false;
349
350 SetPagePreview(mnRow, mnCol);
351 mnSttPage = nNewSttPage;
352
353 // additional invalidate page status.
354 static sal_uInt16 aInval[] =
355 {
356 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38),
357 FN_STAT_PAGE((20000 + 1180) + 1), 0
358 };
359
360 SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings();
361 rBindings.Invalidate( aInval );
362
363 return true;
364}
365
366void SwPagePreviewWin::SetWinSize( const Size& rNewSize )
367{
368 // We always want the size as pixel units.
369 maPxWinSize = LogicToPixel( rNewSize );
370
371 if( USHRT_MAX(32767 *2 +1) == mnSttPage )
372 {
373 mnSttPage = GetDefSttPage();
374 SetSelectedPage( GetDefSttPage() );
375 }
376
377 if ( mbCalcScaleForPreviewLayout )
378 {
379 mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
380 maScale = GetMapMode().GetScaleX();
381 }
382 mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
383 mnSttPage, maPaintedPreviewDocRect );
384 if ( mbCalcScaleForPreviewLayout )
385 {
386 SetSelectedPage( mnSttPage );
387 mbCalcScaleForPreviewLayout = false;
388 }
389 SetPagePreview(mnRow, mnCol);
390 maScale = GetMapMode().GetScaleX();
391}
392
393OUString SwPagePreviewWin::GetStatusStr( sal_uInt16 nPageCnt ) const
394{
395 // show physical and virtual page number of
396 // selected page, if it's visible.
397 const sal_uInt16 nPageNum = mpPgPreviewLayout->IsPageVisible( mpPgPreviewLayout->SelectedPage() )
398 ? mpPgPreviewLayout->SelectedPage() : std::max<sal_uInt16>(mnSttPage, 1);
399
400 OUStringBuffer aStatusStr;
401 const sal_uInt16 nVirtPageNum = mpPgPreviewLayout->GetVirtPageNumByPageNum( nPageNum );
402 if( nVirtPageNum && nVirtPageNum != nPageNum )
403 {
404 aStatusStr.append( OUString::number(nVirtPageNum) ).append( " " );
405 }
406 aStatusStr.append( OUString::number(nPageNum) ).append( " / " ).append( OUString::number(nPageCnt) );
407 return aStatusStr.makeStringAndClear();
408}
409
410void SwPagePreviewWin::KeyInput( const KeyEvent &rKEvt )
411{
412 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
413 bool bHandled = false;
414 if(!rKeyCode.GetModifier())
415 {
416 sal_uInt16 nSlot = 0;
417 switch(rKeyCode.GetCode())
418 {
419 case KEY_ADD : nSlot = SID_ZOOM_OUT(10000 + 97); break;
420 case KEY_ESCAPE: nSlot = FN_CLOSE_PAGEPREVIEW((20000 + 1250) + 4); break;
421 case KEY_SUBTRACT : nSlot = SID_ZOOM_IN(10000 + 98); break;
422 }
423 if(nSlot)
424 {
425 bHandled = true;
426 mrView.GetViewFrame()->GetDispatcher()->Execute(
427 nSlot, SfxCallMode::ASYNCHRON );
428 }
429 }
430 if( !bHandled && !mrView.KeyInput( rKEvt ) )
431 Window::KeyInput( rKEvt );
432}
433
434void SwPagePreviewWin::Command( const CommandEvent& rCEvt )
435{
436 bool bCallBase = true;
437 switch( rCEvt.GetCommand() )
438 {
439 case CommandEventId::ContextMenu:
440 SfxDispatcher::ExecutePopup();
441 bCallBase = false;
442 break;
443
444 case CommandEventId::Wheel:
445 case CommandEventId::StartAutoScroll:
446 case CommandEventId::AutoScroll:
447 {
448 const CommandWheelData* pData = rCEvt.GetWheelData();
449 if( pData )
450 {
451 const CommandWheelData aDataNew(pData->GetDelta(),pData->GetNotchDelta(),COMMAND_WHEEL_PAGESCROLL(sal_uLong(0xFFFFFFFF)),
452 pData->GetMode(),pData->GetModifier(),pData->IsHorz(), pData->IsDeltaPixel());
453 const CommandEvent aEvent( rCEvt.GetMousePosPixel(),rCEvt.GetCommand(),rCEvt.IsMouseEvent(),&aDataNew);
454 bCallBase = !mrView.HandleWheelCommands( aEvent );
455 }
456 else
457 bCallBase = !mrView.HandleWheelCommands( rCEvt );
458 }
459 break;
460 default:
461 ;
462 }
463
464 if( bCallBase )
465 Window::Command( rCEvt );
466}
467
468void SwPagePreviewWin::MouseButtonDown( const MouseEvent& rMEvt )
469{
470 // consider single-click to set selected page
471 if( MOUSE_LEFT(sal_uInt16(0x0001)) != ( rMEvt.GetModifier() + rMEvt.GetButtons() ) )
472 return;
473
474 Point aPreviewPos( PixelToLogic( rMEvt.GetPosPixel() ) );
475 Point aDocPos;
476 bool bPosInEmptyPage;
477 sal_uInt16 nNewSelectedPage;
478 bool bIsDocPos =
479 mpPgPreviewLayout->IsPreviewPosInDocPreviewPage( aPreviewPos,
480 aDocPos, bPosInEmptyPage, nNewSelectedPage );
481 if ( bIsDocPos && rMEvt.GetClicks() == 2 )
482 {
483 // close page preview, set new cursor position and switch to
484 // normal view.
485 OUString sNewCursorPos = OUString::number( aDocPos.X() ) + ";" +
486 OUString::number( aDocPos.Y() ) + ";";
487 mrView.SetNewCursorPos( sNewCursorPos );
488
489 SfxViewFrame *pTmpFrame = mrView.GetViewFrame();
490 pTmpFrame->GetBindings().Execute( SID_VIEWSHELL0(5000 + 630), nullptr,
491 SfxCallMode::ASYNCHRON );
492 }
493 else if ( bIsDocPos || bPosInEmptyPage )
494 {
495 // show clicked page as the selected one
496 mpPgPreviewLayout->MarkNewSelectedPage( nNewSelectedPage );
497 GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
498 // adjust position at vertical scrollbar.
499 if ( mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() )
500 {
501 mrView.SetVScrollbarThumbPos( nNewSelectedPage );
502 }
503 // invalidate page status.
504 static sal_uInt16 aInval[] =
505 {
506 FN_STAT_PAGE((20000 + 1180) + 1), 0
507 };
508 SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings();
509 rBindings.Invalidate( aInval );
510 }
511}
512
513// Set user prefs or view options
514
515void SwPagePreviewWin::SetPagePreview( sal_uInt8 nRow, sal_uInt8 nCol )
516{
517 SwMasterUsrPref *pOpt = const_cast<SwMasterUsrPref *>(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetUsrPref(false));
518
519 if (nRow != pOpt->GetPagePrevRow() || nCol != pOpt->GetPagePrevCol())
520 {
521 pOpt->SetPagePrevRow( nRow );
522 pOpt->SetPagePrevCol( nCol );
523 pOpt->SetModified();
524
525 // Update scrollbar!
526 mrView.ScrollViewSzChg();
527 }
528}
529
530/** get selected page in document preview */
531sal_uInt16 SwPagePreviewWin::SelectedPage() const
532{
533 return mpPgPreviewLayout->SelectedPage();
534}
535
536/** set selected page number in document preview */
537void SwPagePreviewWin::SetSelectedPage( sal_uInt16 _nSelectedPageNum )
538{
539 mpPgPreviewLayout->SetSelectedPage( _nSelectedPageNum );
540}
541
542/** method to enable/disable book preview */
543bool SwPagePreviewWin::SetBookPreviewMode( const bool _bBookPreview )
544{
545 return mpPgPreviewLayout->SetBookPreviewMode( _bBookPreview,
546 mnSttPage,
547 maPaintedPreviewDocRect );
548}
549
550void SwPagePreviewWin::DataChanged( const DataChangedEvent& rDCEvt )
551{
552 Window::DataChanged( rDCEvt );
553
554 switch( rDCEvt.GetType() )
555 {
556 case DataChangedEventType::SETTINGS:
557 // Rearrange the scrollbars or trigger resize, because the
558 // size of the scrollbars may have be changed. Also the
559 // size of the scrollbars has to be retrieved from the settings
560 // out of the resize handler.
561 if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
562 mrView.InvalidateBorder(); // Scrollbar widths
563 // zoom has to be disabled if Accessibility support is switched on
564 lcl_InvalidateZoomSlots(mrView.GetViewFrame()->GetBindings());
565 break;
566
567 case DataChangedEventType::PRINTER:
568 case DataChangedEventType::DISPLAY:
569 case DataChangedEventType::FONTS:
570 case DataChangedEventType::FONTSUBSTITUTION:
571 mrView.GetDocShell()->UpdateFontList(); // Font change
572 mpViewShell->InvalidateLayout(true);
573 if ( mpViewShell->GetWin() )
574 mpViewShell->GetWin()->Invalidate();
575 break;
576 default: break;
577 }
578}
579
580/** help method to execute SfxRequest FN_PAGEUP and FN_PAGEDOWN */
581void SwPagePreview::ExecPgUpAndPgDown( const bool _bPgUp,
582 SfxRequest* _pReq )
583{
584 SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
585 // check, if top/bottom of preview is *not* already visible.
586 if( pPagePreviewLay->GetWinPagesScrollAmount( _bPgUp ? -1 : 1 ) != 0 )
587 {
588 if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() &&
589 pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() )
590 {
591 const int eMvMode = _bPgUp ?
592 SwPagePreviewWin::MV_PAGE_UP :
593 SwPagePreviewWin::MV_PAGE_DOWN;
594 if ( ChgPage( eMvMode ) )
595 m_pViewWin->Invalidate();
596 }
597 else
598 {
599 SwTwips nScrollAmount;
600 sal_uInt16 nNewSelectedPageNum = 0;
601 const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
602 if( _bPgUp )
603 {
604 if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
605 {
606 nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( -1 );
607 if ( (m_pViewWin->SelectedPage() - nVisPages) > 0 )
608 nNewSelectedPageNum = m_pViewWin->SelectedPage() - nVisPages;
609 else
610 nNewSelectedPageNum = 1;
611 }
612 else
613 nScrollAmount = - std::min( m_pViewWin->GetOutputSize().Height(),
614 m_pViewWin->GetPaintedPreviewDocRect().Top() );
615 }
616 else
617 {
618 if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() )
619 {
620 nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( 1 );
621 if ( (m_pViewWin->SelectedPage() + nVisPages) <= mnPageCount )
622 nNewSelectedPageNum = m_pViewWin->SelectedPage() + nVisPages;
623 else
624 nNewSelectedPageNum = mnPageCount;
625 }
626 else
627 nScrollAmount = std::min( m_pViewWin->GetOutputSize().Height(),
628 ( pPagePreviewLay->GetPreviewDocSize().Height() -
629 m_pViewWin->GetPaintedPreviewDocRect().Bottom() ) );
630 }
631 m_pViewWin->Scroll( 0, nScrollAmount );
632 if ( nNewSelectedPageNum != 0 )
633 {
634 m_pViewWin->SetSelectedPage( nNewSelectedPageNum );
635 }
636 ScrollViewSzChg();
637 // additional invalidate page status.
638 static sal_uInt16 aInval[] =
639 {
640 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38),
641 FN_STAT_PAGE((20000 + 1180) + 1), 0
642 };
643 SfxBindings& rBindings = GetViewFrame()->GetBindings();
644 rBindings.Invalidate( aInval );
645 m_pViewWin->Invalidate();
646 }
647 }
648
649 if ( _pReq )
650 _pReq->Done();
651}
652
653// Then all for the SwPagePreview
654void SwPagePreview::Execute( SfxRequest &rReq )
655{
656 int eMvMode = SwPagePreviewWin::MV_DOC_END;
657 sal_uInt8 nRow = 1;
658 bool bRefresh = true;
659
660 switch(rReq.GetSlot())
661 {
662 case FN_REFRESH_VIEW((20000 + 200) + 1):
663 case FN_STAT_PAGE((20000 + 1180) + 1):
664 case FN_STAT_ZOOM((20000 + 1180) + 3):
665 break;
666
667 case FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2):
668 {
669 const SfxItemSet *pArgs = rReq.GetArgs();
670 if( pArgs && pArgs->Count() >= 2 )
671 {
672 sal_uInt8 nCols = static_cast<sal_uInt8>(pArgs->Get(SID_ATTR_TABLE_COLUMNTypedWhichId<SfxUInt16Item>( 10000 + 218 )).GetValue());
673 sal_uInt8 nRows = static_cast<sal_uInt8>(pArgs->Get(SID_ATTR_TABLE_ROWTypedWhichId<SfxUInt16Item>( 10000 + 219 )).GetValue());
674 m_pViewWin->CalcWish( nRows, nCols );
675
676 }
677 else
678 {
679 SwPreviewZoomDlg aDlg(*m_pViewWin);
680 aDlg.execute();
681 }
682 }
683 break;
684 case FN_SHOW_BOOKVIEW((20000 + 1250) + 5):
685 {
686 const SfxItemSet* pArgs = rReq.GetArgs();
687 const SfxPoolItem* pItem;
688 bool bBookPreview = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
689 if( pArgs && SfxItemState::SET == pArgs->GetItemState( FN_SHOW_BOOKVIEW((20000 + 1250) + 5), false, &pItem ) )
690 {
691 bBookPreview = static_cast< const SfxBoolItem* >( pItem )->GetValue();
692 const_cast<SwViewOption*>(GetViewShell()->GetViewOptions())->SetPagePrevBookview( bBookPreview );
693 // cast is not gentleman like, but it's common use in writer and in this case
694 }
695 if ( m_pViewWin->SetBookPreviewMode( bBookPreview ) )
696 {
697 // book preview mode changed. Thus, adjust scrollbars and
698 // invalidate corresponding states.
699 ScrollViewSzChg();
700 static sal_uInt16 aInval[] =
701 {
702 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38),
703 FN_STAT_PAGE((20000 + 1180) + 1), FN_SHOW_BOOKVIEW((20000 + 1250) + 5), 0
704 };
705 SfxBindings& rBindings = GetViewFrame()->GetBindings();
706 rBindings.Invalidate( aInval );
707 m_pViewWin->Invalidate();
708 }
709
710 }
711 break;
712 case FN_SHOW_TWO_PAGES((20000 + 1250) + 1):
713 m_pViewWin->CalcWish( nRow, 2 );
714 break;
715
716 case FN_SHOW_SINGLE_PAGE((20000 + 1250) + 6):
717 m_pViewWin->CalcWish( nRow, 1 );
718 break;
719
720 case FN_PREVIEW_ZOOM((20000 + 200) + 51):
721 case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0):
722 {
723 const SfxItemSet *pArgs = rReq.GetArgs();
724 const SfxPoolItem* pItem;
725 ScopedVclPtr<AbstractSvxZoomDialog> pDlg;
726 if(!pArgs)
727 {
728 SfxItemSet aCoreSet(GetPool(), svl::Items<SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0)>{});
729 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
730 SvxZoomItem aZoom( pVOpt->GetZoomType(), pVOpt->GetZoom() );
731 aZoom.SetValueSet(
732 SvxZoomEnableFlags::N50|
733 SvxZoomEnableFlags::N75|
734 SvxZoomEnableFlags::N100|
735 SvxZoomEnableFlags::N150|
736 SvxZoomEnableFlags::N200|
737 SvxZoomEnableFlags::WHOLEPAGE);
738 aCoreSet.Put( aZoom );
739
740 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
741 pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame()->GetWindow().GetFrameWeld(), aCoreSet));
742 pDlg->SetLimits( MINZOOM20, MAXZOOM600 );
743
744 if( pDlg->Execute() != RET_CANCEL )
745 pArgs = pDlg->GetOutputItemSet();
746 }
747 if( pArgs )
748 {
749 SvxZoomType eType = SvxZoomType::PERCENT;
750 sal_uInt16 nZoomFactor = USHRT_MAX(32767 *2 +1);
751 if(SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), true, &pItem))
752 {
753 eType = static_cast<const SvxZoomItem *>(pItem)->GetType();
754 nZoomFactor = static_cast<const SvxZoomItem *>(pItem)->GetValue();
755 }
756 else if(SfxItemState::SET == pArgs->GetItemState(FN_PREVIEW_ZOOM((20000 + 200) + 51), true, &pItem))
757 nZoomFactor = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
758 if(USHRT_MAX(32767 *2 +1) != nZoomFactor)
759 SetZoom(eType, nZoomFactor);
760 }
761 }
762 break;
763 case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) :
764 {
765 const SfxItemSet *pArgs = rReq.GetArgs();
766 const SfxPoolItem* pItem;
767
768 if ( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMSLIDER( 10000 + 1065 ), true, &pItem ) )
769 {
770 const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue();
771 SetZoom( SvxZoomType::PERCENT, nCurrentZoom );
772 }
773 }
774 break;
775 case SID_ZOOM_IN(10000 + 98):
776 case SID_ZOOM_OUT(10000 + 97):
777 {
778 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
779 SetZoom(SvxZoomType::PERCENT,
780 lcl_GetNextZoomStep(pVOpt->GetZoom(), SID_ZOOM_IN(10000 + 98) == rReq.GetSlot()));
781 }
782 break;
783 case FN_CHAR_LEFT((20000 + 900) + 1 ):
784 case FN_CHAR_RIGHT((20000 + 900) + 2 ):
785 case FN_LINE_UP((20000 + 900) + 3 ):
786 case FN_LINE_DOWN((20000 + 900) + 4 ):
787 {
788 SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
789 sal_uInt16 nNewSelectedPage;
790 sal_uInt16 nNewStartPage;
791 Point aNewStartPos;
792 sal_Int16 nHoriMove = 0;
793 sal_Int16 nVertMove = 0;
794 switch(rReq.GetSlot())
795 {
796 case FN_CHAR_LEFT((20000 + 900) + 1 ): nHoriMove = -1; break;
797 case FN_CHAR_RIGHT((20000 + 900) + 2 ): nHoriMove = 1; break;
798 case FN_LINE_UP((20000 + 900) + 3 ): nVertMove = -1; break;
799 case FN_LINE_DOWN((20000 + 900) + 4 ): nVertMove = 1; break;
800 }
801 pPagePreviewLay->CalcStartValuesForSelectedPageMove( nHoriMove, nVertMove,
802 nNewSelectedPage, nNewStartPage, aNewStartPos );
803 if ( m_pViewWin->SelectedPage() != nNewSelectedPage )
804 {
805 if ( pPagePreviewLay->IsPageVisible( nNewSelectedPage ) )
806 {
807 pPagePreviewLay->MarkNewSelectedPage( nNewSelectedPage );
808 // adjust position at vertical scrollbar.
809 SetVScrollbarThumbPos( nNewSelectedPage );
810 bRefresh = false;
811 }
812 else
813 {
814 m_pViewWin->SetSelectedPage( nNewSelectedPage );
815 m_pViewWin->SetSttPage( nNewStartPage );
816 bRefresh = ChgPage( SwPagePreviewWin::MV_SELPAGE );
817 }
818 GetViewShell()->ShowPreviewSelection( nNewSelectedPage );
819 // invalidate page status.
820 static sal_uInt16 aInval[] =
821 {
822 FN_STAT_PAGE((20000 + 1180) + 1), 0
823 };
824 SfxBindings& rBindings = GetViewFrame()->GetBindings();
825 rBindings.Invalidate( aInval );
826 rReq.Done();
827 }
828 else
829 {
830 bRefresh = false;
831 }
832 break;
833 }
834 case FN_PAGEUP((20000 + 900) + 37):
835 case FN_PAGEDOWN((20000 + 900) + 38):
836 {
837 ExecPgUpAndPgDown( rReq.GetSlot() == FN_PAGEUP((20000 + 900) + 37), &rReq );
838 break;
839 }
840 case SID_JUMP_TO_SPECIFIC_PAGE((20000 + 900) + 92):
841 {
842 const SfxItemSet *pArgs = rReq.GetArgs();
843 if( pArgs && pArgs->Count())
844 {
845 sal_uInt16 nPageNum = static_cast<const SfxUInt16Item &>(pArgs->Get(SID_JUMP_TO_SPECIFIC_PAGE((20000 + 900) + 92))).GetValue();
846
847 if( nPageNum > 0 && nPageNum <= mnPageCount )
848 {
849 m_pViewWin->SetSttPage( nPageNum);
850 m_pViewWin->SetSelectedPage( nPageNum );
851 ChgPage( SwPagePreviewWin::MV_SPECIFIC_PAGE, false );
852 ScrollViewSzChg();
853 }
854 }
855 }
856 break;
857 case FN_START_OF_LINE((20000 + 900) + 5 ):
858 case FN_START_OF_DOCUMENT((20000 + 900) + 7 ):
859 eMvMode = SwPagePreviewWin::MV_DOC_STT;
860 [[fallthrough]];
861 case FN_END_OF_LINE((20000 + 900) + 6 ):
862 case FN_END_OF_DOCUMENT((20000 + 900) + 8):
863 m_pViewWin->SetSelectedPage(eMvMode == SwPagePreviewWin::MV_DOC_STT ? 1 : mnPageCount);
864 {
865 bool bRet = ChgPage( eMvMode );
866 // return value for Basic
867 rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), !bRet));
868
869 bRefresh = bRet;
870 rReq.Done();
871 }
872 break;
873
874 case FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3):
875 {
876 const SwPagePreviewPrtData* pPPVPD = m_pViewWin->GetViewShell()->GetDoc()->GetPreviewPrtData();
877 // The thing with the orientation
878 if(pPPVPD)
879 {
880 SfxPrinter* pPrinter = GetPrinter( true );
881 if((pPrinter->GetOrientation() == Orientation::Landscape)
882 != pPPVPD->GetLandscape())
883 pPrinter->SetOrientation(pPPVPD->GetLandscape() ? Orientation::Landscape : Orientation::Portrait);
884 }
885 ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
886 m_bNormalPrint = false;
887 rReq.SetSlot( SID_PRINTDOC(5000 + 504) );
888 SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
889 rReq.SetSlot( FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3) );
890 return;
891 }
892 case SID_PRINTDOCDIRECT(5000 + 509):
893 case SID_PRINTDOC(5000 + 504):
894 ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false );
895 m_bNormalPrint = true;
896 SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() );
897 return;
898 case FN_CLOSE_PAGEPREVIEW((20000 + 1250) + 4):
899 case SID_PRINTPREVIEW(5000 + 325):
900 // print preview is now always in the same frame as the tab view
901 // -> always switch this frame back to normal view
902 // (ScTabViewShell ctor reads stored view data)
903 GetViewFrame()->GetDispatcher()->Execute( SID_VIEWSHELL0(5000 + 630), SfxCallMode::ASYNCHRON );
904 break;
905 case FN_INSERT_BREAK((20000 + 300) + 3):
906 {
907 sal_uInt16 nSelPage = m_pViewWin->SelectedPage();
908 //if a dummy page is selected (e.g. a non-existing right/left page)
909 //the direct neighbor is used
910 if(GetViewShell()->IsDummyPage( nSelPage ) && GetViewShell()->IsDummyPage( --nSelPage ))
911 nSelPage +=2;
912 m_nNewPage = nSelPage;
913 SfxViewFrame *pTmpFrame = GetViewFrame();
914 pTmpFrame->GetBindings().Execute( SID_VIEWSHELL0(5000 + 630), nullptr,
915 SfxCallMode::ASYNCHRON );
916 }
917 break;
918 default:
919 OSL_ENSURE(false, "wrong dispatcher")do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx"
":" "919" ": "), "%s", "wrong dispatcher"); } } while (false
)
;
920 return;
921 }
922
923 if( bRefresh )
924 m_pViewWin->Invalidate();
925}
926
927void SwPagePreview::GetState( SfxItemSet& rSet )
928{
929 SfxWhichIter aIter(rSet);
930 sal_uInt16 nWhich = aIter.FirstWhich();
931 OSL_ENSURE(nWhich, "empty set")do { if (true && (!(nWhich))) { sal_detail_logFormat(
(SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx"
":" "931" ": "), "%s", "empty set"); } } while (false)
;
932 SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
933
934 while(nWhich)
935 {
936 switch(nWhich)
937 {
938 case SID_BROWSER_MODE(5000 + 1313):
939 case FN_PRINT_LAYOUT((20000 + 200) + 37):
940 rSet.DisableItem(nWhich);
941 break;
942 case FN_START_OF_DOCUMENT((20000 + 900) + 7 ):
943 {
944 if ( pPagePreviewLay->IsPageVisible( 1 ) )
945 rSet.DisableItem(nWhich);
946 break;
947 }
948 case FN_END_OF_DOCUMENT((20000 + 900) + 8):
949 {
950 if ( pPagePreviewLay->IsPageVisible( mnPageCount ) )
951 rSet.DisableItem(nWhich);
952 break;
953 }
954 case FN_PAGEUP((20000 + 900) + 37):
955 {
956 if( pPagePreviewLay->GetWinPagesScrollAmount( -1 ) == 0 )
957 rSet.DisableItem(nWhich);
958 break;
959 }
960 case FN_PAGEDOWN((20000 + 900) + 38):
961 {
962 if( pPagePreviewLay->GetWinPagesScrollAmount( 1 ) == 0 )
963 rSet.DisableItem(nWhich);
964 break;
965 }
966
967 case FN_STAT_PAGE((20000 + 1180) + 1):
968 {
969 OUString aStr = m_sPageStr + m_pViewWin->GetStatusStr( mnPageCount );
970 rSet.Put( SfxStringItem( nWhich, aStr) );
971 }
972 break;
973
974 case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0):
975 case FN_STAT_ZOOM((20000 + 1180) + 3):
976 {
977 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
978 SvxZoomItem aZoom(pVOpt->GetZoomType(), pVOpt->GetZoom());
979 aZoom.SetValueSet(
980 SvxZoomEnableFlags::N50|
981 SvxZoomEnableFlags::N75|
982 SvxZoomEnableFlags::N100|
983 SvxZoomEnableFlags::N150|
984 SvxZoomEnableFlags::N200);
985 rSet.Put( aZoom );
986 }
987 break;
988 case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) :
989 {
990 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
991 const sal_uInt16 nCurrentZoom = pVOpt->GetZoom();
992 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM20, MAXZOOM600 );
993 aZoomSliderItem.AddSnappingPoint( 100 );
994 rSet.Put( aZoomSliderItem );
995 }
996 break;
997 case FN_PREVIEW_ZOOM((20000 + 200) + 51):
998 {
999 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
1000 rSet.Put(SfxUInt16Item(nWhich, pVOpt->GetZoom()));
1001 }
1002 break;
1003 case SID_ZOOM_IN(10000 + 98):
1004 case SID_ZOOM_OUT(10000 + 97):
1005 {
1006 const SwViewOption* pVOpt = GetViewShell()->GetViewOptions();
1007 if((SID_ZOOM_OUT(10000 + 97) == nWhich && pVOpt->GetZoom() >= MAX_PREVIEW_ZOOM600)||
1008 (SID_ZOOM_IN(10000 + 98) == nWhich && pVOpt->GetZoom() <= MIN_PREVIEW_ZOOM25))
1009 {
1010 rSet.DisableItem(nWhich);
1011 }
1012 }
1013 break;
1014 case FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2):
1015 // should never be disabled
1016 break;
1017 case FN_SHOW_BOOKVIEW((20000 + 1250) + 5):
1018 {
1019 bool b = GetViewShell()->GetViewOptions()->IsPagePrevBookview();
1020 rSet.Put(SfxBoolItem(nWhich, b));
1021 }
1022 break;
1023
1024 case FN_SHOW_TWO_PAGES((20000 + 1250) + 1):
1025 if( 2 == m_pViewWin->GetCol() && 1 == m_pViewWin->GetRow() )
1026 rSet.DisableItem( nWhich );
1027 break;
1028
1029 case FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3):
1030 // has the same status like the normal printing
1031 {
1032 const SfxPoolItem* pItem;
1033 SfxItemSet aSet( *rSet.GetPool(), svl::Items<SID_PRINTDOC(5000 + 504), SID_PRINTDOC(5000 + 504)>{} );
1034 GetSlotState( SID_PRINTDOC(5000 + 504), SfxViewShell::GetInterface(), &aSet );
1035 if( SfxItemState::DISABLED == aSet.GetItemState( SID_PRINTDOC(5000 + 504),
1036 false, &pItem ))
1037 rSet.DisableItem( nWhich );
1038 else if( SfxItemState::SET == aSet.GetItemState( SID_PRINTDOC(5000 + 504),
1039 false, &pItem ))
1040 {
1041 const_cast<SfxPoolItem*>(pItem)->SetWhich( FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3) );
1042 rSet.Put( *pItem );
1043 }
1044 }
1045 break;
1046
1047 case SID_PRINTPREVIEW(5000 + 325):
1048 rSet.Put( SfxBoolItem( nWhich, true ) );
1049 break;
1050
1051 case SID_PRINTDOC(5000 + 504):
1052 case SID_PRINTDOCDIRECT(5000 + 509):
1053 GetSlotState( nWhich, SfxViewShell::GetInterface(), &rSet );
1054 break;
1055 }
1056 nWhich = aIter.NextWhich();
1057 }
1058}
1059
1060void SwPagePreview::StateUndo(SfxItemSet& rSet)
1061{
1062 SfxWhichIter aIter(rSet);
1063 sal_uInt16 nWhich = aIter.FirstWhich();
1064
1065 while (nWhich)
1066 {
1067 rSet.DisableItem(nWhich);
1068 nWhich = aIter.NextWhich();
1069 }
1070}
1071
1072void SwPagePreview::Init()
1073{
1074 if ( GetViewShell()->HasDrawView() )
1075 GetViewShell()->GetDrawView()->SetAnimationEnabled( false );
1076
1077 m_bNormalPrint = true;
1078
1079 // Check and process the DocSize. The shell could not be found via
1080 // the handler, because the shell is unknown to the SFX management
1081 // within the CTOR phase.
1082
1083 const SwViewOption * pPrefs = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetUsrPref(false);
1084
1085 mbHScrollbarEnabled = pPrefs->IsViewHScrollBar();
1086 mbVScrollbarEnabled = pPrefs->IsViewVScrollBar();
1087
1088 // Update the fields
1089 // ATTENTION: Do cast the EditShell up, to use the SS.
1090 // At the methods the current shell will be queried!
1091 SwEditShell* pESh = dynamic_cast<SwEditShell*>(GetViewShell());
1092 bool bIsModified = pESh != nullptr && pESh->IsModified();
1093
1094 SwViewOption aOpt( *pPrefs );
1095 aOpt.SetPagePreview(true);
1096 aOpt.SetTab( false );
1097 aOpt.SetBlank( false );
1098 aOpt.SetHardBlank( false );
1099 aOpt.SetParagraph( false );
1100 aOpt.SetLineBreak( false );
1101 aOpt.SetPageBreak( false );
1102 aOpt.SetColumnBreak( false );
1103 aOpt.SetSoftHyph( false );
1104 aOpt.SetFieldName( false );
1105 aOpt.SetPostIts( false );
1106 aOpt.SetShowBookmarks( false );
1107 aOpt.SetShowHiddenChar( false );
1108 aOpt.SetShowHiddenField( false );
1109 aOpt.SetShowHiddenPara( false );
1110 aOpt.SetViewHRuler( false );
1111 aOpt.SetViewVRuler( false );
1112 aOpt.SetGraphic( true );
1113 aOpt.SetTable( true );
1114 aOpt.SetSnap( false );
1115 aOpt.SetGridVisible( false );
1116 aOpt.SetOnlineSpell( false );
1117 aOpt.SetHideWhitespaceMode( false );
1118
1119 GetViewShell()->ApplyViewOptions( aOpt );
1120 GetViewShell()->ApplyAccessibilityOptions(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetAccessibilityOptions());
1121
1122 // adjust view shell option to the same as for print
1123 SwPrintData const aPrintOptions = *SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule
::Writer)))
->GetPrtOptions(false);
1124 GetViewShell()->AdjustOptionsForPagePreview( aPrintOptions );
1125
1126 GetViewShell()->CalcLayout();
1127 DocSzChgd( GetViewShell()->GetDocSize() );
1128
1129 if( !bIsModified && pESh != nullptr )
1130 pESh->ResetModified();
1131}
1132
1133SwPagePreview::SwPagePreview(SfxViewFrame *pViewFrame, SfxViewShell* pOldSh):
1134 SfxViewShell( pViewFrame, SWVIEWFLAGSSfxViewShellFlags::HAS_PRINTOPTIONS ),
1135 m_pViewWin( VclPtr<SwPagePreviewWin>::Create(&GetViewFrame()->GetWindow(), *this ) ),
1136 m_nNewPage(USHRT_MAX(32767 *2 +1)),
1137 m_sPageStr(SwResId(STR_PAGEreinterpret_cast<char const *>("STR_PAGE" "\004" u8"Page "
)
)),
1138 m_pHScrollbar(nullptr),
1139 m_pVScrollbar(nullptr),
1140 m_pScrollFill(VclPtr<ScrollBarBox>::Create( &pViewFrame->GetWindow(), WB_SIZEABLE )),
1141 mnPageCount( 0 ),
1142 mbResetFormDesignMode( false ),
1143 mbFormDesignModeToReset( false )
1144{
1145 SetName("PageView");
1146 SetWindow( m_pViewWin );
1147 CreateScrollbar( true );
1148 CreateScrollbar( false );
1149
1150 //notify notebookbar change in context
1151 SfxShell::SetContextBroadcasterEnabled(true);
1152 SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview));
1153 SfxShell::BroadcastContextForActivation(true);
1154 //removelisteners for notebookbar
1155 if (SfxViewFrame* pCurrent = SfxViewFrame::Current())
1156 if (auto& pBar = pCurrent->GetWindow().GetSystemWindow()->GetNotebookBar())
1157 pBar->ControlListenerForCurrentController(false);
1158
1159 SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
1160 if ( !pOldSh )
1161 {
1162 // Exists already a view on the document?
1163 SfxViewFrame *pF = SfxViewFrame::GetFirst( pObjShell );
1164 if ( pF == pViewFrame )
1165 pF = SfxViewFrame::GetNext( *pF, pObjShell );
1166 if ( pF )
1167 pOldSh = pF->GetViewShell();
1168 }
1169
1170 SwViewShell *pVS, *pNew;
1171
1172 if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview*>(pOldSh))
1173 pVS = pPagePreview->GetViewShell();
1174 else
1175 {
1176 if (SwView* pView = dynamic_cast<SwView *>(pOldSh))
1177 {
1178 pVS = pView->GetWrtShellPtr();
1179 // save the current ViewData of the previous SwView
1180 pOldSh->WriteUserData( m_sSwViewData );
1181 }
1182 else
1183 pVS = GetDocShell()->GetWrtShell();
1184 if( pVS )
1185 {
1186 // Set the current page as the first.
1187 sal_uInt16 nPhysPg, nVirtPg;
1188 static_cast<SwCursorShell*>(pVS)->GetPageNum( nPhysPg, nVirtPg, true, false );
1189 if( 1 != m_pViewWin->GetCol() && 1 == nPhysPg )
1190 --nPhysPg;
1191 m_pViewWin->SetSttPage( nPhysPg );
1192 }
1193 }
1194
1195 // for form shell remember design mode of draw view
1196 // of previous view shell
1197 if ( pVS && pVS->HasDrawView() )
1198 {
1199 mbResetFormDesignMode = true;
1200 mbFormDesignModeToReset = pVS->GetDrawView()->IsDesignMode();
1201 }
1202
1203 if( pVS )
1204 pNew = new SwViewShell( *pVS, m_pViewWin, nullptr, VSHELLFLAG_ISPREVIEW(long(0x1)) );
1205 else
1206 pNew = new SwViewShell(
1207 *static_cast<SwDocShell*>(pViewFrame->GetObjectShell())->GetDoc(),
1208 m_pViewWin, nullptr, nullptr, VSHELLFLAG_ISPREVIEW(long(0x1)) );
1209
1210 m_pViewWin->SetViewShell( pNew );
1211 pNew->SetSfxViewShell( this );
1212 Init();
1213}
1214
1215SwPagePreview::~SwPagePreview()
1216{
1217 SetWindow( nullptr );
1218 SwViewShell* pVShell = m_pViewWin->GetViewShell();
1219 pVShell->SetWin(nullptr);
1220 delete pVShell;
1221
1222 m_pViewWin.disposeAndClear();
1
Calling 'VclPtr::disposeAndClear'
1223 if (SfxViewFrame* pCurrent = SfxViewFrame::Current())
1224 if (auto& pBar = pCurrent->GetWindow().GetSystemWindow()->GetNotebookBar())
1225 pBar->ControlListenerForCurrentController(true); // start listening now
1226 m_pScrollFill.disposeAndClear();
1227 m_pHScrollbar.disposeAndClear();
1228 m_pVScrollbar.disposeAndClear();
1229}
1230
1231SwDocShell* SwPagePreview::GetDocShell()
1232{
1233 return dynamic_cast<SwDocShell*>( GetViewFrame()->GetObjectShell() );
1234}
1235
1236void SwPagePreview::CreateScrollbar( bool bHori )
1237{
1238 vcl::Window *pMDI = &GetViewFrame()->GetWindow();
1239 VclPtr<SwScrollbar>& ppScrollbar = bHori ? m_pHScrollbar : m_pVScrollbar;
1240
1241 assert(!ppScrollbar)(static_cast <bool> (!ppScrollbar) ? void (0) : __assert_fail
("!ppScrollbar", "/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx"
, 1241, __extension__ __PRETTY_FUNCTION__))
; //check beforehand!
1242
1243 ppScrollbar = VclPtr<SwScrollbar>::Create( pMDI, bHori );
1244
1245 ScrollDocSzChg();
1246 ppScrollbar->EnableDrag();
1247 ppScrollbar->SetEndScrollHdl( LINK( this, SwPagePreview, EndScrollHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwPagePreview
*>(this), &SwPagePreview::LinkStubEndScrollHdl)
);
1248
1249 ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, ScrollHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwPagePreview
*>(this), &SwPagePreview::LinkStubScrollHdl)
);
1250
1251 InvalidateBorder();
1252 ppScrollbar->ExtendedShow();
1253}
1254
1255bool SwPagePreview::ChgPage( int eMvMode, bool bUpdateScrollbar )
1256{
1257 tools::Rectangle aPixVisArea( m_pViewWin->LogicToPixel( m_aVisArea ) );
1258 bool bChg = m_pViewWin->MovePage( eMvMode ) ||
1259 eMvMode == SwPagePreviewWin::MV_CALC ||
1260 eMvMode == SwPagePreviewWin::MV_NEWWINSIZE;
1261 m_aVisArea = m_pViewWin->PixelToLogic( aPixVisArea );
1262
1263 if( bChg )
1264 {
1265 // Update statusbar
1266 OUString aStr = m_sPageStr + m_pViewWin->GetStatusStr( mnPageCount );
1267 SfxBindings& rBindings = GetViewFrame()->GetBindings();
1268
1269 if( bUpdateScrollbar )
1270 {
1271 ScrollViewSzChg();
1272
1273 static sal_uInt16 aInval[] =
1274 {
1275 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8),
1276 FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), 0
1277 };
1278 rBindings.Invalidate( aInval );
1279 }
1280 rBindings.SetState( SfxStringItem( FN_STAT_PAGE((20000 + 1180) + 1), aStr ) );
1281 }
1282 return bChg;
1283}
1284
1285// From here, everything was taken from the SwView.
1286void SwPagePreview::CalcAndSetBorderPixel( SvBorder &rToFill )
1287{
1288 const StyleSettings &rSet = m_pViewWin->GetSettings().GetStyleSettings();
1289 const long nTmp = rSet.GetScrollBarSize();
1290 if ( m_pVScrollbar->IsVisible( true ) )
1291 rToFill.Right() = nTmp;
1292 if ( m_pHScrollbar->IsVisible( true ) )
1293 rToFill.Bottom() = nTmp;
1294 SetBorderPixel( rToFill );
1295}
1296
1297void SwPagePreview::InnerResizePixel( const Point &rOfst, const Size &rSize, bool )
1298{
1299 SvBorder aBorder;
1300 CalcAndSetBorderPixel( aBorder );
1301 tools::Rectangle aRect( rOfst, rSize );
1302 aRect += aBorder;
1303 ViewResizePixel( *m_pViewWin, aRect.TopLeft(), aRect.GetSize(),
1304 m_pViewWin->GetOutputSizePixel(),
1305 *m_pVScrollbar, *m_pHScrollbar, *m_pScrollFill );
1306
1307 // Never set EditWin !
1308 // Never set VisArea !
1309}
1310
1311void SwPagePreview::OuterResizePixel( const Point &rOfst, const Size &rSize )
1312{
1313 SvBorder aBorder;
1314 CalcAndSetBorderPixel( aBorder );
1315
1316 // Never set EditWin !
1317
1318 Size aTmpSize( m_pViewWin->GetOutputSizePixel() );
1319 Point aBottomRight( m_pViewWin->PixelToLogic( Point( aTmpSize.Width(), aTmpSize.Height() ) ) );
1320 SetVisArea( tools::Rectangle( Point(), aBottomRight ) );
1321
1322 // Call of the DocSzChgd-Method of the scrollbars is necessary,
1323 // because from the maximum scroll range half the height of the
1324 // VisArea is always deducted.
1325 if ( m_pVScrollbar && !aTmpSize.IsEmpty() )
1326 {
1327 ScrollDocSzChg();
1328 }
1329
1330 SvBorder aBorderNew;
1331 CalcAndSetBorderPixel( aBorderNew );
1332 ViewResizePixel( *m_pViewWin, rOfst, rSize, m_pViewWin->GetOutputSizePixel(),
1333 *m_pVScrollbar, *m_pHScrollbar, *m_pScrollFill );
1334}
1335
1336void SwPagePreview::SetVisArea( const tools::Rectangle &rRect )
1337{
1338 const Point aTopLeft(AlignToPixel(rRect.TopLeft()));
1339 const Point aBottomRight(AlignToPixel(rRect.BottomRight()));
1340 tools::Rectangle aLR(aTopLeft,aBottomRight);
1341
1342 if(aLR == m_aVisArea)
1343 return;
1344 // No negative position, no negative size
1345
1346 if(aLR.Top() < 0)
1347 {
1348 aLR.AdjustBottom(std::abs(aLR.Top()) );
1349 aLR.SetTop( 0 );
1350 }
1351
1352 if(aLR.Left() < 0)
1353 {
1354 aLR.AdjustRight(std::abs(aLR.Left()) );
1355 aLR.SetLeft( 0 );
1356 }
1357 if(aLR.Right() < 0) aLR.SetRight( 0 );
1358 if(aLR.Bottom() < 0) aLR.SetBottom( 0 );
1359 if(aLR == m_aVisArea ||
1360 // Ignore empty rectangle
1361 ( 0 == aLR.Bottom() - aLR.Top() && 0 == aLR.Right() - aLR.Left() ) )
1362 return;
1363
1364 if( aLR.Left() > aLR.Right() || aLR.Top() > aLR.Bottom() )
1365 return;
1366
1367 // Before the data can be changed call an update if necessary.
1368 // Thereby ensured, that adjacent paints are correctly converted into
1369 // document coordinates.
1370 // As a precaution, we do this only when at the shell runs an action,
1371 // because then we do not really paint but the rectangles are just
1372 // bookmarked (in document coordinates).
1373 if( GetViewShell()->ActionPend() )
1374 m_pViewWin->PaintImmediately();
1375
1376 // Set at View-Win the current size
1377 m_aVisArea = aLR;
1378 m_pViewWin->SetWinSize( aLR.GetSize() );
1379 ChgPage( SwPagePreviewWin::MV_NEWWINSIZE );
1380
1381 m_pViewWin->Invalidate();
1382}
1383
1384IMPL_LINK( SwPagePreview, ScrollHdl, ScrollBar *, p, void )void SwPagePreview::LinkStubScrollHdl(void * instance, ScrollBar
* data) { return static_cast<SwPagePreview *>(instance
)->ScrollHdl(data); } void SwPagePreview::ScrollHdl(ScrollBar
* p)
1385{
1386 SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p);
1387 if(!GetViewShell())
1388 return;
1389 if( !pScrollbar->IsHoriScroll() &&
1390 pScrollbar->GetType() == ScrollType::Drag &&
1391 Help::IsQuickHelpEnabled() &&
1392 GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
1393 {
1394 // Scroll how many pages??
1395 OUString sStateStr(m_sPageStr);
1396 long nThmbPos = pScrollbar->GetThumbPos();
1397 if( 1 == m_pViewWin->GetCol() || !nThmbPos )
1398 ++nThmbPos;
1399 sStateStr += OUString::number( nThmbPos );
1400 Point aPos = pScrollbar->GetParent()->OutputToScreenPixel(
1401 pScrollbar->GetPosPixel());
1402 aPos.setY( pScrollbar->OutputToScreenPixel(pScrollbar->GetPointerPosPixel()).Y() );
1403 tools::Rectangle aRect;
1404 aRect.SetLeft( aPos.X() -8 );
1405 aRect.SetRight( aRect.Left() );
1406 aRect.SetTop( aPos.Y() );
1407 aRect.SetBottom( aRect.Top() );
1408
1409 Help::ShowQuickHelp(pScrollbar, aRect, sStateStr,
1410 QuickHelpFlags::Right|QuickHelpFlags::VCenter);
1411
1412 }
1413 else
1414 EndScrollHdl( pScrollbar );
1415}
1416
1417IMPL_LINK( SwPagePreview, EndScrollHdl, ScrollBar *, p, void )void SwPagePreview::LinkStubEndScrollHdl(void * instance, ScrollBar
* data) { return static_cast<SwPagePreview *>(instance
)->EndScrollHdl(data); } void SwPagePreview::EndScrollHdl(
ScrollBar * p)
1418{
1419 SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p);
1420 if(!GetViewShell())
1421 return;
1422
1423 // boolean to avoid unnecessary invalidation of the window.
1424 bool bInvalidateWin = true;
1425
1426 if( !pScrollbar->IsHoriScroll() ) // scroll vertically
1427 {
1428 if ( Help::IsQuickHelpEnabled() )
1429 Help::ShowQuickHelp(pScrollbar, tools::Rectangle(), OUString());
1430 if ( GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow() )
1431 {
1432 // Scroll how many pages ??
1433 const sal_uInt16 nThmbPos = static_cast<sal_uInt16>(pScrollbar->GetThumbPos());
1434 // adjust to new preview functionality
1435 if( nThmbPos != m_pViewWin->SelectedPage() )
1436 {
1437 // consider case that page <nThmbPos>
1438 // is already visible
1439 SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
1440 if ( pPagePreviewLay->IsPageVisible( nThmbPos ) )
1441 {
1442 pPagePreviewLay->MarkNewSelectedPage( nThmbPos );
1443 // invalidation of window is unnecessary
1444 bInvalidateWin = false;
1445 }
1446 else
1447 {
1448 // consider whether layout columns
1449 // fit or not.
1450 if ( !pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() )
1451 {
1452 m_pViewWin->SetSttPage( nThmbPos );
1453 m_pViewWin->SetSelectedPage( nThmbPos );
1454 ChgPage( SwPagePreviewWin::MV_SCROLL, false );
1455 // update scrollbars
1456 ScrollViewSzChg();
1457 }
1458 else
1459 {
1460 // correct scroll amount
1461 const sal_Int16 nPageDiff = nThmbPos - m_pViewWin->SelectedPage();
1462 const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
1463 sal_Int16 nWinPagesToScroll = nPageDiff / nVisPages;
1464 if ( nPageDiff % nVisPages )
1465 {
1466 // decrease/increase number of preview pages to scroll
1467 nPageDiff < 0 ? --nWinPagesToScroll : ++nWinPagesToScroll;
1468 }
1469 m_pViewWin->SetSelectedPage( nThmbPos );
1470 m_pViewWin->Scroll( 0, pPagePreviewLay->GetWinPagesScrollAmount( nWinPagesToScroll ) );
1471 }
1472 }
1473 // update accessibility
1474 GetViewShell()->ShowPreviewSelection( nThmbPos );
1475 }
1476 else
1477 {
1478 // invalidation of window is unnecessary
1479 bInvalidateWin = false;
1480 }
1481 }
1482 else
1483 {
1484 long nThmbPos = pScrollbar->GetThumbPos();
1485 m_pViewWin->Scroll(0, nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Top());
1486 }
1487 }
1488 else
1489 {
1490 long nThmbPos = pScrollbar->GetThumbPos();
1491 m_pViewWin->Scroll(nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Left(), 0);
1492 }
1493 // additional invalidate page status.
1494 static sal_uInt16 aInval[] =
1495 {
1496 FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38),
1497 FN_STAT_PAGE((20000 + 1180) + 1), 0
1498 };
1499 SfxBindings& rBindings = GetViewFrame()->GetBindings();
1500 rBindings.Invalidate( aInval );
1501 // control invalidation of window
1502 if ( bInvalidateWin )
1503 {
1504 m_pViewWin->Invalidate();
1505 }
1506}
1507
1508Point SwPagePreview::AlignToPixel(const Point &rPt) const
1509{
1510 return m_pViewWin->PixelToLogic( m_pViewWin->LogicToPixel( rPt ) );
1511}
1512
1513void SwPagePreview::DocSzChgd( const Size &rSz )
1514{
1515 if( m_aDocSize == rSz )
1516 return;
1517
1518 m_aDocSize = rSz;
1519
1520 // #i96726#
1521 // Due to the multiple page layout it is needed to trigger recalculation
1522 // of the page preview layout, even if the count of pages is not changing.
1523 mnPageCount = GetViewShell()->GetNumPages();
1524
1525 if( m_aVisArea.GetWidth() )
1526 {
1527 ChgPage( SwPagePreviewWin::MV_CALC );
1528 ScrollDocSzChg();
1529
1530 m_pViewWin->Invalidate();
1531 }
1532}
1533
1534void SwPagePreview::ScrollViewSzChg()
1535{
1536 if(!GetViewShell())
1537 return ;
1538
1539 bool bShowVScrollbar = false, bShowHScrollbar = false;
1540
1541 if(m_pVScrollbar)
1542 {
1543 if(GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow())
1544 {
1545 //vertical scrolling by row
1546 // adjust to new preview functionality
1547 const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol();
1548
1549 m_pVScrollbar->SetVisibleSize( nVisPages );
1550 // set selected page as scroll bar position,
1551 // if it is visible.
1552 SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout();
1553 if ( pPagePreviewLay->IsPageVisible( m_pViewWin->SelectedPage() ) )
1554 {
1555 m_pVScrollbar->SetThumbPos( m_pViewWin->SelectedPage() );
1556 }
1557 else
1558 {
1559 m_pVScrollbar->SetThumbPos( m_pViewWin->GetSttPage() );
1560 }
1561 m_pVScrollbar->SetLineSize( m_pViewWin->GetCol() );
1562 m_pVScrollbar->SetPageSize( nVisPages );
1563 // calculate and set scrollbar range
1564 Range aScrollbarRange( 1, mnPageCount );
1565 // increase range by one, because left-top-corner is left blank.
1566 ++aScrollbarRange.Max();
1567 // increase range in order to access all pages
1568 aScrollbarRange.Max() += ( nVisPages - 1 );
1569 m_pVScrollbar->SetRange( aScrollbarRange );
1570
1571 bShowVScrollbar = nVisPages < mnPageCount;
1572 }
1573 else //vertical scrolling by pixel
1574 {
1575 const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
1576 const Size& rPreviewSize =
1577 GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
1578 m_pVScrollbar->SetRangeMax(rPreviewSize.Height()) ;
1579 long nVisHeight = rDocRect.GetHeight();
1580 m_pVScrollbar->SetVisibleSize( nVisHeight );
1581 m_pVScrollbar->SetThumbPos( rDocRect.Top() );
1582 m_pVScrollbar->SetLineSize( nVisHeight / 10 );
1583 m_pVScrollbar->SetPageSize( nVisHeight / 2 );
1584
1585 bShowVScrollbar = true;
1586 }
1587
1588 if (!mbVScrollbarEnabled)
1589 bShowVScrollbar = false;
1590
1591 ShowVScrollbar(bShowVScrollbar);
1592 }
1593 if(m_pHScrollbar)
1594 {
1595 const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect();
1596 const Size& rPreviewSize =
1597 GetViewShell()->PagePreviewLayout()->GetPreviewDocSize();
1598 Range aRange(0,0);
1599
1600 if(rDocRect.GetWidth() < rPreviewSize.Width())
1601 {
1602 bShowHScrollbar = true;
1603
1604 long nVisWidth = rDocRect.GetWidth();
1605 long nThumb = rDocRect.Left();
1606 aRange = Range(0, rPreviewSize.Width());
1607
1608 m_pHScrollbar->SetRange( aRange );
1609 m_pHScrollbar->SetVisibleSize( nVisWidth );
1610 m_pHScrollbar->SetThumbPos( nThumb );
1611 m_pHScrollbar->SetLineSize( nVisWidth / 10 );
1612 m_pHScrollbar->SetPageSize( nVisWidth / 2 );
1613 }
1614
1615 if (!mbHScrollbarEnabled)
1616 bShowHScrollbar = false;
1617
1618 ShowHScrollbar(bShowHScrollbar);
1619 }
1620 m_pScrollFill->Show(bShowVScrollbar && bShowHScrollbar);
1621}
1622
1623void SwPagePreview::ScrollDocSzChg()
1624{
1625 ScrollViewSzChg();
1626}
1627
1628// All about printing
1629SfxPrinter* SwPagePreview::GetPrinter( bool bCreate )
1630{
1631 return m_pViewWin->GetViewShell()->getIDocumentDeviceAccess().getPrinter( bCreate );
1632}
1633
1634sal_uInt16 SwPagePreview::SetPrinter( SfxPrinter *pNew, SfxPrinterChangeFlags nDiffFlags )
1635{
1636 SwViewShell &rSh = *GetViewShell();
1637 SfxPrinter* pOld = rSh.getIDocumentDeviceAccess().getPrinter( false );
1638 if ( pOld && pOld->IsPrinting() )
1639 return SFX_PRINTERROR_BUSY1;
1640
1641 SwEditShell &rESh = static_cast<SwEditShell&>(rSh); //Buh...
1642 if( ( SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP ) & nDiffFlags )
1643 {
1644 rSh.getIDocumentDeviceAccess().setPrinter( pNew, true, true );
1645 if( nDiffFlags & SfxPrinterChangeFlags::PRINTER )
1646 rESh.SetModified();
1647 }
1648 if ( ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS ) == SfxPrinterChangeFlags::OPTIONS )
1649 ::SetPrinter( &rSh.getIDocumentDeviceAccess(), pNew, false );
1650
1651 const bool bChgOri = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION);
1652 const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE);
1653 if ( bChgOri || bChgSize )
1654 {
1655 rESh.StartAllAction();
1656 if ( bChgOri )
1657 rSh.ChgAllPageOrientation( pNew->GetOrientation() );
1658 if ( bChgSize )
1659 {
1660 Size aSz( SvxPaperInfo::GetPaperSize( pNew ) );
1661 rSh.ChgAllPageSize( aSz );
1662 }
1663 if( !m_bNormalPrint )
1664 m_pViewWin->CalcWish( m_pViewWin->GetRow(), m_pViewWin->GetCol() );
1665 rESh.SetModified();
1666 rESh.EndAllAction();
1667
1668 static sal_uInt16 aInval[] =
1669 {
1670 SID_ATTR_LONG_ULSPACE( 10000 + 284 ), SID_ATTR_LONG_LRSPACE( 10000 + 285 ),
1671 SID_RULER_BORDERSTypedWhichId<SvxRulerItem>( 10000 + 80 ), SID_RULER_PAGE_POSTypedWhichId<SvxRulerItem>( 10000 + 82 ), 0
1672 };
1673#if OSL_DEBUG_LEVEL1 > 0
1674 {
1675 const sal_uInt16* pPtr = aInval + 1;
1676 do {
1677 OSL_ENSURE( *(pPtr - 1) < *pPtr, "wrong sorting!" )do { if (true && (!(*(pPtr - 1) < *pPtr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx"
":" "1677" ": "), "%s", "wrong sorting!"); } } while (false)
;
1678 } while( *++pPtr );
1679 }
1680#endif
1681
1682 GetViewFrame()->GetBindings().Invalidate(aInval);
1683 }
1684
1685 return 0;
1686}
1687
1688bool SwPagePreview::HasPrintOptionsPage() const
1689{
1690 return true;
1691}
1692
1693std::unique_ptr<SfxTabPage> SwPagePreview::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController,
1694 const SfxItemSet &rOptions)
1695{
1696 return ::CreatePrintOptionsPage(pPage, pController, rOptions, !m_bNormalPrint);
1697}
1698
1699void SwPagePreviewWin::SetViewShell( SwViewShell* pShell )
1700{
1701 mpViewShell = pShell;
1702 if ( mpViewShell && mpViewShell->IsPreview() )
1703 {
1704 mpPgPreviewLayout = mpViewShell->PagePreviewLayout();
1705 }
1706}
1707
1708void SwPagePreviewWin::RepaintCoreRect( const SwRect& rRect )
1709{
1710 // #i24183#
1711 if ( mpPgPreviewLayout->PreviewLayoutValid() )
1712 {
1713 mpPgPreviewLayout->Repaint( tools::Rectangle( rRect.Pos(), rRect.SSize() ) );
1714 }
1715}
1716
1717/** method to adjust preview to a new zoom factor
1718
1719 #i19975# also consider zoom type - adding parameter <_eZoomType>
1720*/
1721void SwPagePreviewWin::AdjustPreviewToNewZoom( const sal_uInt16 _nZoomFactor,
1722 const SvxZoomType _eZoomType )
1723{
1724 // #i19975# consider zoom type
1725 if ( _eZoomType == SvxZoomType::WHOLEPAGE )
1726 {
1727 mnRow = 1;
1728 mnCol = 1;
1729 mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize );
1730 mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize,
1731 mnSttPage, maPaintedPreviewDocRect );
1732 SetSelectedPage( mnSttPage );
1733 SetPagePreview(mnRow, mnCol);
1734 maScale = GetMapMode().GetScaleX();
1735 }
1736 else if ( _nZoomFactor != 0 )
1737 {
1738 // calculate new scaling and set mapping mode appropriately.
1739 Fraction aNewScale( _nZoomFactor, 100 );
1740 MapMode aNewMapMode = GetMapMode();
1741 aNewMapMode.SetScaleX( aNewScale );
1742 aNewMapMode.SetScaleY( aNewScale );
1743 SetMapMode( aNewMapMode );
1744
1745 // calculate new start position for preview paint
1746 Size aNewWinSize = PixelToLogic( maPxWinSize );
1747 Point aNewPaintStartPos =
1748 mpPgPreviewLayout->GetPreviewStartPosForNewScale( aNewScale, maScale, aNewWinSize );
1749
1750 // remember new scaling and prepare preview paint
1751 // Note: paint of preview will be performed by a corresponding invalidate
1752 // due to property changes.
1753 maScale = aNewScale;
1754 mpPgPreviewLayout->Prepare( 0, aNewPaintStartPos, maPxWinSize,
1755 mnSttPage, maPaintedPreviewDocRect );
1756 }
1757
1758}
1759
1760/**
1761 * pixel scrolling - horizontally always or vertically
1762 * when less than the desired number of rows fits into
1763 * the view
1764 */
1765void SwPagePreviewWin::Scroll(long nXMove, long nYMove, ScrollFlags /*nFlags*/)
1766{
1767 maPaintedPreviewDocRect.Move(nXMove, nYMove);
1768 mpPgPreviewLayout->Prepare( 0, maPaintedPreviewDocRect.TopLeft(),
1769 maPxWinSize, mnSttPage,
1770 maPaintedPreviewDocRect );
1771
1772}
1773
1774bool SwPagePreview::HandleWheelCommands( const CommandEvent& rCEvt )
1775{
1776 bool bOk = false;
1777 const CommandWheelData* pWData = rCEvt.GetWheelData();
1778 if( pWData && CommandWheelMode::ZOOM == pWData->GetMode() )
1779 {
1780 //only the Preference shouldn't control the Zoom, it is better to detect AT tools running. So the bridge can be used here
1781 if (!Application::GetSettings().GetMiscSettings().GetEnableATToolSupport())
1782 {
1783 sal_uInt16 nFactor = GetViewShell()->GetViewOptions()->GetZoom();
1784 const sal_uInt16 nOffset = 10;
1785 if( 0L > pWData->GetDelta() )
1786 {
1787 nFactor -= nOffset;
1788 if(nFactor < MIN_PREVIEW_ZOOM25)
1789 nFactor = MIN_PREVIEW_ZOOM25;
1790 }
1791 else
1792 {
1793 nFactor += nOffset;
1794 if(nFactor > MAX_PREVIEW_ZOOM600)
1795 nFactor = MAX_PREVIEW_ZOOM600;
1796 }
1797 SetZoom(SvxZoomType::PERCENT, nFactor);
1798 }
1799 bOk = true;
1800 }
1801 else
1802 bOk = m_pViewWin->HandleScrollCommand( rCEvt, m_pHScrollbar, m_pVScrollbar );
1803 return bOk;
1804}
1805
1806uno::Reference< css::accessibility::XAccessible >
1807 SwPagePreviewWin::CreateAccessible()
1808{
1809 SolarMutexGuard aGuard; // this should have happened already!!!
1810
1811 OSL_ENSURE( GetViewShell() != nullptr, "We need a view shell" )do { if (true && (!(GetViewShell() != nullptr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx"
":" "1811" ": "), "%s", "We need a view shell"); } } while (
false)
;
1812 css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible( false );
1813 if (xAcc.is())
1814 {
1815 return xAcc;
1816 }
1817 if (mpViewShell)
1818 {
1819 css::uno::Reference< css::accessibility::XAccessible > xAccPreview = mpViewShell->CreateAccessiblePreview();
1820 SetAccessible(xAccPreview);
1821 }
1822 return GetAccessible( false );
1823}
1824
1825void SwPagePreview::ApplyAccessibilityOptions(SvtAccessibilityOptions const & rAccessibilityOptions)
1826{
1827 GetViewShell()->ApplyAccessibilityOptions(rAccessibilityOptions);
1828}
1829
1830void SwPagePreview::ShowHScrollbar(bool bShow)
1831{
1832 m_pHScrollbar->Show(bShow);
1833 InvalidateBorder();
1834}
1835
1836void SwPagePreview::ShowVScrollbar(bool bShow)
1837{
1838 m_pVScrollbar->Show(bShow);
1839 InvalidateBorder();
1840}
1841
1842void SwPagePreview::EnableHScrollbar(bool bEnable)
1843{
1844 if (mbHScrollbarEnabled != bEnable)
1845 {
1846 mbHScrollbarEnabled = bEnable;
1847 ScrollViewSzChg();
1848 }
1849}
1850
1851void SwPagePreview::EnableVScrollbar(bool bEnable)
1852{
1853 if (mbVScrollbarEnabled != bEnable)
1854 {
1855 mbVScrollbarEnabled = bEnable;
1856 ScrollViewSzChg();
1857 }
1858}
1859
1860void SwPagePreview::SetZoom(SvxZoomType eType, sal_uInt16 nFactor)
1861{
1862 SwViewShell& rSh = *GetViewShell();
1863 SwViewOption aOpt(*rSh.GetViewOptions());
1864 // perform action only on changes of zoom or zoom type.
1865 if ( aOpt.GetZoom() != nFactor ||
1866 aOpt.GetZoomType() != eType )
1867 {
1868 aOpt.SetZoom(nFactor);
1869 aOpt.SetZoomType(eType);
1870 rSh.ApplyViewOptions( aOpt );
1871 lcl_InvalidateZoomSlots(GetViewFrame()->GetBindings());
1872 // #i19975# also consider zoom type
1873 m_pViewWin->AdjustPreviewToNewZoom( nFactor, eType );
1874 ScrollViewSzChg();
1875 }
1876}
1877
1878/** adjust position of vertical scrollbar */
1879void SwPagePreview::SetVScrollbarThumbPos( const sal_uInt16 _nNewThumbPos )
1880{
1881 if ( m_pVScrollbar )
1882 {
1883 m_pVScrollbar->SetThumbPos( _nNewThumbPos );
1884 }
1885}
1886
1887/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_VCL_PTR_HXX
21#define INCLUDED_VCL_PTR_HXX
22
23#include <sal/config.h>
24
25#include <rtl/ref.hxx>
26
27#include <utility>
28#include <type_traits>
29
30#ifdef DBG_UTIL
31#ifndef _WIN32
32#include <vcl/vclmain.hxx>
33#endif
34#endif
35
36class VclReferenceBase;
37
38namespace vcl::detail {
39
40template<typename>
41constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; }
42
43template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase(
44 int (*)[sizeof(T)])
45{ return std::is_base_of<VclReferenceBase, T>::value; }
46
47} // namespace vcl::detail
48
49/**
50 * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
51 *
52 * For more details on the design please see vcl/README.lifecycle
53 *
54 * @param reference_type must be a subclass of vcl::Window
55 */
56template <class reference_type>
57class VclPtr
58{
59 static_assert(
60 vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>(
61 nullptr),
62 "template argument type must be derived from VclReferenceBase");
63
64 ::rtl::Reference<reference_type> m_rInnerRef;
65
66public:
67 /** Constructor...
68 */
69 VclPtr()
70 : m_rInnerRef()
71 {}
72
73 /** Constructor...
74 */
75 VclPtr (reference_type * pBody)
76 : m_rInnerRef(pBody)
77 {}
78
79 /** Constructor... that doesn't take a ref.
80 */
81 VclPtr (reference_type * pBody, __sal_NoAcquire)
82 : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
83 {}
84
85 /** Up-casting conversion constructor: Copies interface reference.
86
87 Does not work for up-casts to ambiguous bases. For the special case of
88 up-casting to Reference< XInterface >, see the corresponding conversion
89 operator.
90
91 @param rRef another reference
92 */
93 template< class derived_type >
94 VclPtr(
95 const VclPtr< derived_type > & rRef,
96 typename std::enable_if<
97 std::is_base_of<reference_type, derived_type>::value, int>::type
98 = 0 )
99 : m_rInnerRef( static_cast<reference_type*>(rRef) )
100 {
101 }
102
103#if defined(DBG_UTIL) && !defined(_WIN32)
104 virtual ~VclPtr()
105 {
106 assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain
::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 106, __extension__ __PRETTY_FUNCTION__))
;
107 // We can be one of the intermediate counts, but if we are the last
108 // VclPtr keeping this object alive, then something forgot to call dispose().
109 assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
110 && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef
->isDisposed() || m_rInnerRef->getRefCount() > 1) &&
"someone forgot to call dispose()") ? void (0) : __assert_fail
("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\""
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 110, __extension__ __PRETTY_FUNCTION__))
;
111 }
112 VclPtr(VclPtr const &) = default;
113 VclPtr(VclPtr &&) = default;
114 VclPtr & operator =(VclPtr const &) = default;
115 VclPtr & operator =(VclPtr &&) = default;
116#endif
117
118 /**
119 * A construction helper for VclPtr. Since VclPtr types are created
120 * with a reference-count of one - to help fit into the existing
121 * code-flow; this helps us to construct them easily.
122 *
123 * For more details on the design please see vcl/README.lifecycle
124 *
125 * @tparam reference_type must be a subclass of vcl::Window
126 */
127 template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg)
128 {
129 return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
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 ;-)
2
Calling 'Reference::clear'
9
Returning; memory was released
205 if (aTmp.get()) {
10
Calling 'Reference::get'
206 aTmp->disposeOnce();
207 }
208 }
209
210 /** Needed to place VclPtr's into STL collection.
211 */
212 bool operator< (const VclPtr<reference_type> & handle) const
213 {
214 return (m_rInnerRef < handle.m_rInnerRef);
215 }
216}; // class VclPtr
217
218template<typename T1, typename T2>
219inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
220 return p1.get() == p2.get();
221}
222
223template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
224{
225 return p1.get() == p2;
226}
227
228template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
229 return p1.get() == p2;
230}
231
232template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
233{
234 return p1 == p2.get();
235}
236
237template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
238 return p1 == p2.get();
239}
240
241template<typename T1, typename T2>
242inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
243 return !(p1 == p2);
244}
245
246template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
247{
248 return !(p1 == p2);
249}
250
251template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
252 return !(p1 == p2);
253}
254
255template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
256{
257 return !(p1 == p2);
258}
259
260template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
261 return !(p1 == p2);
262}
263
264/**
265 * A construction helper for a temporary VclPtr. Since VclPtr types
266 * are created with a reference-count of one - to help fit into
267 * the existing code-flow; this helps us to construct them easily.
268 * see also VclPtr::Create and ScopedVclPtr
269 *
270 * For more details on the design please see vcl/README.lifecycle
271 *
272 * @param reference_type must be a subclass of vcl::Window
273 */
274template <class reference_type>
275class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type>
276{
277public:
278 template<typename... Arg> VclPtrInstance(Arg &&... arg)
279 : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
280 {
281 }
282
283 /**
284 * Override and disallow this, to prevent people accidentally calling it and actually
285 * getting VclPtr::Create and getting a naked VclPtr<> instance
286 */
287 template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete;
288};
289
290template <class reference_type>
291class ScopedVclPtr : public VclPtr<reference_type>
292{
293public:
294 /** Constructor...
295 */
296 ScopedVclPtr()
297 : VclPtr<reference_type>()
298 {}
299
300 /** Constructor
301 */
302 ScopedVclPtr (reference_type * pBody)
303 : VclPtr<reference_type>(pBody)
304 {}
305
306 /** Copy constructor...
307 */
308 ScopedVclPtr (const VclPtr<reference_type> & handle)
309 : VclPtr<reference_type>(handle)
310 {}
311
312 /**
313 Assignment that releases the last reference.
314 */
315 void disposeAndReset(reference_type *pBody)
316 {
317 if (pBody != this->get()) {
318 VclPtr<reference_type>::disposeAndClear();
319 VclPtr<reference_type>::set(pBody);
320 }
321 }
322
323 /**
324 Assignment that releases the last reference.
325 */
326 ScopedVclPtr<reference_type>& operator = (reference_type * pBody)
327 {
328 disposeAndReset(pBody);
329 return *this;
330 }
331
332 /** Up-casting conversion constructor: Copies interface reference.
333
334 Does not work for up-casts to ambiguous bases. For the special case of
335 up-casting to Reference< XInterface >, see the corresponding conversion
336 operator.
337
338 @param rRef another reference
339 */
340 template< class derived_type >
341 ScopedVclPtr(
342 const VclPtr< derived_type > & rRef,
343 typename std::enable_if<
344 std::is_base_of<reference_type, derived_type>::value, int>::type
345 = 0 )
346 : VclPtr<reference_type>( rRef )
347 {
348 }
349
350 /** Up-casting assignment operator.
351
352 Does not work for up-casts to ambiguous bases.
353
354 @param rRef another VclPtr
355 */
356 template<typename derived_type>
357 typename std::enable_if<
358 std::is_base_of<reference_type, derived_type>::value,
359 ScopedVclPtr &>::type
360 operator =(VclPtr<derived_type> const & rRef)
361 {
362 disposeAndReset(rRef.get());
363 return *this;
364 }
365
366 /**
367 * Override and disallow this, to prevent people accidentally calling it and actually
368 * getting VclPtr::Create and getting a naked VclPtr<> instance
369 */
370 template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete;
371
372 ~ScopedVclPtr()
373 {
374 VclPtr<reference_type>::disposeAndClear();
375 assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get(
) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr"
, "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx"
, 375, __extension__ __PRETTY_FUNCTION__))
; // make sure there are no lingering references
376 }
377
378private:
379 // Most likely we don't want this default copy-constructor.
380 ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete;
381 // And certainly we don't want a default assignment operator.
382 ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete;
383 // And disallow reset as that doesn't call disposeAndClear on the original reference
384 void reset() = delete;
385 void reset(reference_type *pBody) = delete;
386
387protected:
388 ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
389 : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
390 {}
391};
392
393/**
394 * A construction helper for ScopedVclPtr. Since VclPtr types are created
395 * with a reference-count of one - to help fit into the existing
396 * code-flow; this helps us to construct them easily.
397 *
398 * For more details on the design please see vcl/README.lifecycle
399 *
400 * @param reference_type must be a subclass of vcl::Window
401 */
402#if defined _MSC_VER
403#pragma warning(push)
404#pragma warning(disable: 4521) // " multiple copy constructors specified"
405#endif
406template <class reference_type>
407class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type>
408{
409public:
410 template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
411 : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
412 {
413 }
414
415 /**
416 * Override and disallow this, to prevent people accidentally calling it and actually
417 * getting VclPtr::Create and getting a naked VclPtr<> instance
418 */
419 template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete;
420
421private:
422 // Prevent the above perfect forwarding ctor from hijacking (accidental)
423 // attempts at ScopedVclPtrInstance copy construction (where the hijacking
424 // would typically lead to somewhat obscure error messages); both non-const
425 // and const variants are needed here, as the ScopedVclPtr base class has a
426 // const--variant copy ctor, so the implicitly declared copy ctor for
427 // ScopedVclPtrInstance would also be the const variant, so non-const copy
428 // construction attempts would be hijacked by the perfect forwarding ctor;
429 // but if we only declared a non-const variant here, the const variant would
430 // no longer be implicitly declared (as there would already be an explicitly
431 // declared copy ctor), so const copy construction attempts would then be
432 // hijacked by the perfect forwarding ctor:
433 ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete;
434 ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete;
435};
436#if defined _MSC_VER
437#pragma warning(pop)
438#endif
439
440#endif // INCLUDED_VCL_PTR_HXX
441
442/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

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

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody)
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
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
)
3
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
4
Calling 'VclReferenceBase::release'
8
Returning; memory was released
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;
11
Use of memory after it is freed
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
5
Assuming the condition is true
6
Taking true branch
40 delete this;
7
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif