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 viewprn.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 SFX2_DLLIMPLEMENTATION -D ENABLE_CUPS -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sfx2/inc -I /home/maarten/src/libreoffice/core/sfx2/source/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sfx2/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/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/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/sfx2/source/view/viewprn.cxx

/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.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 <memory>
21
22#include <com/sun/star/document/XDocumentProperties.hpp>
23#include <com/sun/star/view/XRenderable.hpp>
24#include <com/sun/star/view/XSelectionSupplier.hpp>
25#include <officecfg/Office/Common.hxx>
26#include <sal/log.hxx>
27#include <svl/itempool.hxx>
28#include <vcl/svapp.hxx>
29#include <vcl/weld.hxx>
30#include <svtools/prnsetup.hxx>
31#include <svl/flagitem.hxx>
32#include <svl/stritem.hxx>
33#include <svl/eitem.hxx>
34#include <sfx2/app.hxx>
35#include <unotools/useroptions.hxx>
36#include <tools/datetime.hxx>
37#include <sfx2/bindings.hxx>
38#include <sfx2/objface.hxx>
39#include <sfx2/viewsh.hxx>
40#include "viewimp.hxx"
41#include <sfx2/viewfrm.hxx>
42#include <sfx2/printer.hxx>
43#include <sfx2/sfxresid.hxx>
44#include <sfx2/request.hxx>
45#include <sfx2/objsh.hxx>
46#include <sfx2/event.hxx>
47#include <sfx2/docfile.hxx>
48#include <sfx2/docfilt.hxx>
49#include <sfx2/sfxsids.hrc>
50#include <sfx2/strings.hrc>
51#include <sfx2/sfxuno.hxx>
52#include <sfx2/tabdlg.hxx>
53
54#include <toolkit/awt/vclxdevice.hxx>
55
56#include "prnmon.hxx"
57
58using namespace com::sun::star;
59using namespace com::sun::star::uno;
60
61class SfxPrinterController : public vcl::PrinterController, public SfxListener
62{
63 Any maCompleteSelection;
64 Any maSelection;
65 Reference< view::XRenderable > mxRenderable;
66 mutable VclPtr<Printer> mpLastPrinter;
67 mutable Reference<awt::XDevice> mxDevice;
68 SfxViewShell* mpViewShell;
69 SfxObjectShell* mpObjectShell;
70 bool m_bOrigStatus;
71 bool m_bNeedsChange;
72 bool m_bApi;
73 bool m_bTempPrinter;
74 util::DateTime m_aLastPrinted;
75 OUString m_aLastPrintedBy;
76
77 Sequence< beans::PropertyValue > getMergedOptions() const;
78 const Any& getSelectionObject() const;
79
80public:
81 SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
82 const Any& i_rComplete,
83 const Any& i_rSelection,
84 const Any& i_rViewProp,
85 const Reference< view::XRenderable >& i_xRender,
86 bool i_bApi, bool i_bDirect,
87 SfxViewShell* pView,
88 const uno::Sequence< beans::PropertyValue >& rProps
89 );
90
91 virtual void Notify( SfxBroadcaster&, const SfxHint& ) override;
92
93 virtual int getPageCount() const override;
94 virtual Sequence< beans::PropertyValue > getPageParameters( int i_nPage ) const override;
95 virtual void printPage( int i_nPage ) const override;
96 virtual void jobStarted() override;
97 virtual void jobFinished( css::view::PrintableState ) override;
98};
99
100SfxPrinterController::SfxPrinterController( const VclPtr<Printer>& i_rPrinter,
101 const Any& i_rComplete,
102 const Any& i_rSelection,
103 const Any& i_rViewProp,
104 const Reference< view::XRenderable >& i_xRender,
105 bool i_bApi, bool i_bDirect,
106 SfxViewShell* pView,
107 const uno::Sequence< beans::PropertyValue >& rProps
108 )
109 : PrinterController(i_rPrinter, pView ? pView->GetFrameWeld() : nullptr)
110 , maCompleteSelection( i_rComplete )
111 , maSelection( i_rSelection )
112 , mxRenderable( i_xRender )
113 , mpLastPrinter( nullptr )
114 , mpViewShell( pView )
115 , mpObjectShell(nullptr)
116 , m_bOrigStatus( false )
117 , m_bNeedsChange( false )
118 , m_bApi(i_bApi)
119 , m_bTempPrinter( i_rPrinter )
120{
121 if ( mpViewShell )
122 {
123 StartListening( *mpViewShell );
124 mpObjectShell = mpViewShell->GetObjectShell();
125 StartListening( *mpObjectShell );
126 }
127
128 // initialize extra ui options
129 if( mxRenderable.is() )
130 {
131 for (const auto& rProp : rProps)
132 setValue( rProp.Name, rProp.Value );
133
134 Sequence< beans::PropertyValue > aRenderOptions( 3 );
135 aRenderOptions[0].Name = "ExtraPrintUIOptions";
136 aRenderOptions[1].Name = "View" ;
137 aRenderOptions[1].Value = i_rViewProp;
138 aRenderOptions[2].Name = "IsPrinter";
139 aRenderOptions[2].Value <<= true;
140 try
141 {
142 const Sequence< beans::PropertyValue > aRenderParms( mxRenderable->getRenderer( 0 , getSelectionObject(), aRenderOptions ) );
143 for( const auto& rRenderParm : aRenderParms )
144 {
145 if ( rRenderParm.Name == "ExtraPrintUIOptions" )
146 {
147 Sequence< beans::PropertyValue > aUIProps;
148 rRenderParm.Value >>= aUIProps;
149 setUIOptions( aUIProps );
150 }
151 else if( rRenderParm.Name == "NUp" )
152 {
153 setValue( rRenderParm.Name, rRenderParm.Value );
154 }
155 }
156 }
157 catch( lang::IllegalArgumentException& )
158 {
159 // the first renderer should always be available for the UI options,
160 // but catch the exception to be safe
161 }
162 }
163
164 // set some job parameters
165 setValue( "IsApi", makeAny( i_bApi ) );
166 setValue( "IsDirect", makeAny( i_bDirect ) );
167 setValue( "IsPrinter", makeAny( true ) );
168 setValue( "View", i_rViewProp );
169}
170
171void SfxPrinterController::Notify( SfxBroadcaster& , const SfxHint& rHint )
172{
173 if ( rHint.GetId() == SfxHintId::Dying )
174 {
175 EndListening(*mpViewShell);
176 EndListening(*mpObjectShell);
177 mpViewShell = nullptr;
178 mpObjectShell = nullptr;
179 }
180}
181
182const Any& SfxPrinterController::getSelectionObject() const
183{
184 const beans::PropertyValue* pVal = getValue( OUString( "PrintSelectionOnly" ) );
185 if( pVal )
186 {
187 bool bSel = false;
188 pVal->Value >>= bSel;
189 return bSel ? maSelection : maCompleteSelection;
190 }
191
192 sal_Int32 nChoice = 0;
193 pVal = getValue( OUString( "PrintContent" ) );
194 if( pVal )
195 pVal->Value >>= nChoice;
196
197 return (nChoice > 1) ? maSelection : maCompleteSelection;
198}
199
200Sequence< beans::PropertyValue > SfxPrinterController::getMergedOptions() const
201{
202 VclPtr<Printer> xPrinter( getPrinter() );
203 if( xPrinter.get() != mpLastPrinter )
204 {
205 mpLastPrinter = xPrinter.get();
206 VCLXDevice* pXDevice = new VCLXDevice();
207 pXDevice->SetOutputDevice( mpLastPrinter );
208 mxDevice.set( pXDevice );
209 }
210
211 Sequence< beans::PropertyValue > aRenderOptions( 1 );
212 aRenderOptions[ 0 ].Name = "RenderDevice";
213 aRenderOptions[ 0 ].Value <<= mxDevice;
214
215 aRenderOptions = getJobProperties( aRenderOptions );
216 return aRenderOptions;
217}
218
219int SfxPrinterController::getPageCount() const
220{
221 int nPages = 0;
222 VclPtr<Printer> xPrinter( getPrinter() );
223 if( mxRenderable.is() && xPrinter )
224 {
225 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
226 try
227 {
228 nPages = mxRenderable->getRendererCount( getSelectionObject(), aJobOptions );
229 }
230 catch (lang::DisposedException &)
231 {
232 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "232" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "232" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "232" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "232" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
233 const_cast<SfxPrinterController*>(this)->setJobState(
234 view::PrintableState_JOB_ABORTED);
235 }
236 }
237 return nPages;
238}
239
240Sequence< beans::PropertyValue > SfxPrinterController::getPageParameters( int i_nPage ) const
241{
242 VclPtr<Printer> xPrinter( getPrinter() );
243 Sequence< beans::PropertyValue > aResult;
244
245 if (mxRenderable.is() && xPrinter)
246 {
247 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
248 try
249 {
250 aResult = mxRenderable->getRenderer( i_nPage, getSelectionObject(), aJobOptions );
251 }
252 catch( lang::IllegalArgumentException& )
253 {
254 }
255 catch (lang::DisposedException &)
256 {
257 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "257" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "257" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "257" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "257" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
258 const_cast<SfxPrinterController*>(this)->setJobState(
259 view::PrintableState_JOB_ABORTED);
260 }
261 }
262 return aResult;
263}
264
265void SfxPrinterController::printPage( int i_nPage ) const
266{
267 VclPtr<Printer> xPrinter( getPrinter() );
268 if( !mxRenderable.is() || !xPrinter )
269 return;
270
271 Sequence< beans::PropertyValue > aJobOptions( getMergedOptions() );
272 try
273 {
274 mxRenderable->render( i_nPage, getSelectionObject(), aJobOptions );
275 }
276 catch( lang::IllegalArgumentException& )
277 {
278 // don't care enough about nonexistent page here
279 // to provoke a crash
280 }
281 catch (lang::DisposedException &)
282 {
283 SAL_WARN("sfx", "SfxPrinterController: document disposed while printing")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "283" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "283" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SfxPrinterController: document disposed while printing"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"
), ("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "283" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SfxPrinterController: document disposed while printing"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SfxPrinterController: document disposed while printing"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx"),
("/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
":" "283" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
284 const_cast<SfxPrinterController*>(this)->setJobState(
285 view::PrintableState_JOB_ABORTED);
286 }
287}
288
289void SfxPrinterController::jobStarted()
290{
291 if ( !mpObjectShell )
292 return;
293
294 m_bOrigStatus = mpObjectShell->IsEnableSetModified();
295
296 // check configuration: shall update of printing information in DocInfo set the document to "modified"?
297 if (m_bOrigStatus && !officecfg::Office::Common::Print::PrintingModifiesDocument::get())
298 {
299 mpObjectShell->EnableSetModified( false );
300 m_bNeedsChange = true;
301 }
302
303 // refresh document info
304 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
305 m_aLastPrintedBy = xDocProps->getPrintedBy();
306 m_aLastPrinted = xDocProps->getPrintDate();
307
308 xDocProps->setPrintedBy( mpObjectShell->IsUseUserData()
309 ? SvtUserOptions().GetFullName()
310 : OUString() );
311 ::DateTime now( ::DateTime::SYSTEM );
312
313 xDocProps->setPrintDate( now.GetUNODateTime() );
314
315 SfxGetpApp()->NotifyEvent( SfxEventHint(SfxEventHintId::PrintDoc, GlobalEventConfig::GetEventName( GlobalEventId::PRINTDOC ), mpObjectShell ) );
316 uno::Sequence < beans::PropertyValue > aOpts;
317 aOpts = getJobProperties( aOpts );
318
319 uno::Reference< frame::XController2 > xController;
320 if ( mpViewShell )
321 xController.set( mpViewShell->GetController(), uno::UNO_QUERY );
322
323 mpObjectShell->Broadcast( SfxPrintingHint(
324 view::PrintableState_JOB_STARTED, aOpts, mpObjectShell, xController ) );
325}
326
327void SfxPrinterController::jobFinished( css::view::PrintableState nState )
328{
329 if ( !mpObjectShell )
330 return;
331
332 bool bCopyJobSetup = false;
333 mpObjectShell->Broadcast( SfxPrintingHint( nState ) );
334 switch ( nState )
335 {
336 case view::PrintableState_JOB_SPOOLING_FAILED :
337 case view::PrintableState_JOB_FAILED :
338 {
339 // "real" problem (not simply printing cancelled by user)
340 OUString aMsg( SfxResId(STR_NOSTARTPRINTERreinterpret_cast<char const *>("STR_NOSTARTPRINTER" "\004"
u8"Could not start printer.\nPlease check your printer configuration."
)
) );
341 if ( !m_bApi )
342 {
343 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(mpViewShell->GetFrameWeld(),
344 VclMessageType::Warning, VclButtonsType::Ok,
345 aMsg));
346 xBox->run();
347 }
348 [[fallthrough]];
349 }
350 case view::PrintableState_JOB_ABORTED :
351 {
352 // printing not successful, reset DocInfo
353 uno::Reference<document::XDocumentProperties> xDocProps(mpObjectShell->getDocProperties());
354 xDocProps->setPrintedBy(m_aLastPrintedBy);
355 xDocProps->setPrintDate(m_aLastPrinted);
356 break;
357 }
358
359 case view::PrintableState_JOB_SPOOLED :
360 case view::PrintableState_JOB_COMPLETED :
361 {
362 SfxBindings& rBind = mpViewShell->GetViewFrame()->GetBindings();
363 rBind.Invalidate( SID_PRINTDOC(5000 + 504) );
364 rBind.Invalidate( SID_PRINTDOCDIRECT(5000 + 509) );
365 rBind.Invalidate( SID_SETUPPRINTER(5000 + 302) );
366 bCopyJobSetup = ! m_bTempPrinter;
367 break;
368 }
369
370 default:
371 break;
372 }
373
374 if( bCopyJobSetup && mpViewShell )
375 {
376 // #i114306#
377 // Note: this possibly creates a printer that gets immediately replaced
378 // by a new one. The reason for this is that otherwise we would not get
379 // the printer's SfxItemSet here to copy. Awkward, but at the moment there is no
380 // other way here to get the item set.
381 SfxPrinter* pDocPrt = mpViewShell->GetPrinter(true);
382 if( pDocPrt )
383 {
384 if( pDocPrt->GetName() == getPrinter()->GetName() )
385 pDocPrt->SetJobSetup( getPrinter()->GetJobSetup() );
386 else
387 {
388 VclPtr<SfxPrinter> pNewPrt = VclPtr<SfxPrinter>::Create( pDocPrt->GetOptions().Clone(), getPrinter()->GetName() );
389 pNewPrt->SetJobSetup( getPrinter()->GetJobSetup() );
390 mpViewShell->SetPrinter( pNewPrt, SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP );
391 }
392 }
393 }
394
395 if ( m_bNeedsChange )
396 mpObjectShell->EnableSetModified( m_bOrigStatus );
397
398 if ( mpViewShell )
399 {
400 mpViewShell->pImpl->m_xPrinterController.reset();
401 }
402}
403
404namespace {
405
406/**
407 An instance of this class is created for the life span of the
408 printer dialogue, to create in its click handler for the additions by the
409 virtual method of the derived SfxViewShell generated print options dialogue
410 and to cache the options set there as SfxItemSet.
411*/
412class SfxDialogExecutor_Impl
413{
414private:
415 SfxViewShell* _pViewSh;
416 PrinterSetupDialog& _rSetupParent;
417 std::unique_ptr<SfxItemSet> _pOptions;
418 bool _bHelpDisabled;
419
420 DECL_LINK( Execute, weld::Button&, void )static void LinkStubExecute(void *, weld::Button&); void Execute
(weld::Button&)
;
421
422public:
423 SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent );
424
425 Link<weld::Button&, void> GetLink() const { return LINK(const_cast<SfxDialogExecutor_Impl*>(this), SfxDialogExecutor_Impl, Execute)::tools::detail::makeLink( ::tools::detail::castTo<SfxDialogExecutor_Impl
*>(const_cast<SfxDialogExecutor_Impl*>(this)), &
SfxDialogExecutor_Impl::LinkStubExecute)
; }
426 const SfxItemSet* GetOptions() const { return _pOptions.get(); }
427 void DisableHelp() { _bHelpDisabled = true; }
428};
429
430}
431
432SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent ) :
433
434 _pViewSh ( pViewSh ),
435 _rSetupParent ( rParent ),
436 _bHelpDisabled ( false )
437
438{
439}
440
441IMPL_LINK_NOARG(SfxDialogExecutor_Impl, Execute, weld::Button&, void)void SfxDialogExecutor_Impl::LinkStubExecute(void * instance,
weld::Button& data) { return static_cast<SfxDialogExecutor_Impl
*>(instance)->Execute(data); } void SfxDialogExecutor_Impl
::Execute(__attribute__ ((unused)) weld::Button&)
442{
443 // Options noted locally
444 if ( !_pOptions )
445 {
446 _pOptions = static_cast<SfxPrinter*>( _rSetupParent.GetPrinter() )->GetOptions().Clone();
447 }
448
449 assert(_pOptions)(static_cast <bool> (_pOptions) ? void (0) : __assert_fail
("_pOptions", "/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
, 449, __extension__ __PRETTY_FUNCTION__))
;
450 if (!_pOptions)
451 return;
452
453 // Create Dialog
454 SfxPrintOptionsDialog aDlg(_rSetupParent.GetFrameWeld(), _pViewSh, _pOptions.get() );
455 if (_bHelpDisabled)
456 aDlg.DisableHelp();
457 if (aDlg.run() == RET_OK)
458 {
459 _pOptions = aDlg.GetOptions().Clone();
460 }
461}
462
463/**
464 Internal method for setting the differences between 'pNewPrinter' to the
465 current printer. pNewPrinter is either taken over or deleted.
466*/
467void SfxViewShell::SetPrinter_Impl( VclPtr<SfxPrinter>& pNewPrinter )
468{
469 // get current Printer
470 SfxPrinter *pDocPrinter = GetPrinter();
471
472 // Evaluate Printer Options
473 sal_uInt16 nWhich = GetPool().GetWhich(SID_PRINTER_CHANGESTODOC(5000 + 324));
474 const SfxFlagItem *pFlagItem = nullptr;
475 pDocPrinter->GetOptions().GetItemState( nWhich, false, reinterpret_cast<const SfxPoolItem**>(&pFlagItem) );
476 bool bOriToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
477 bool bSizeToDoc = pFlagItem && (static_cast<SfxPrinterChangeFlags>(pFlagItem->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
478
479 // Determine the previous format and size
480 Orientation eOldOri = pDocPrinter->GetOrientation();
481 Size aOldPgSz = pDocPrinter->GetPaperSizePixel();
482
483 // Determine the new format and size
484 Orientation eNewOri = pNewPrinter->GetOrientation();
485 Size aNewPgSz = pNewPrinter->GetPaperSizePixel();
486
487 // Determine the changes in page format
488 bool bOriChg = (eOldOri != eNewOri) && bOriToDoc;
489 bool bPgSzChg = ( aOldPgSz.Height() !=
490 ( bOriChg ? aNewPgSz.Width() : aNewPgSz.Height() ) ||
491 aOldPgSz.Width() !=
492 ( bOriChg ? aNewPgSz.Height() : aNewPgSz.Width() ) ) &&
493 bSizeToDoc;
494
495 // Message and Flags for page format changes
496 OUString aMsg;
497 SfxPrinterChangeFlags nNewOpt = SfxPrinterChangeFlags::NONE;
498 if( bOriChg && bPgSzChg )
499 {
500 aMsg = SfxResId(STR_PRINT_NEWORISIZEreinterpret_cast<char const *>("STR_PRINT_NEWORISIZE" "\004"
u8"The page size and orientation have been modified.\nWould you like to save the new settings in the\nactive document?"
)
);
501 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION | SfxPrinterChangeFlags::CHG_SIZE;
502 }
503 else if (bOriChg )
504 {
505 aMsg = SfxResId(STR_PRINT_NEWORIreinterpret_cast<char const *>("STR_PRINT_NEWORI" "\004"
u8"The page size and orientation have been modified.\nWould you like to save the new settings in the\nactive document?"
)
);
506 nNewOpt = SfxPrinterChangeFlags::CHG_ORIENTATION;
507 }
508 else if (bPgSzChg)
509 {
510 aMsg = SfxResId(STR_PRINT_NEWSIZEreinterpret_cast<char const *>("STR_PRINT_NEWSIZE" "\004"
u8"The page size has been modified.\nShould the new settings be saved\nin the active document?"
)
);
511 nNewOpt = SfxPrinterChangeFlags::CHG_SIZE;
512 }
513
514 // Summarize in this variable what has been changed.
515 SfxPrinterChangeFlags nChangedFlags = SfxPrinterChangeFlags::NONE;
516
517 // Ask if possible, if page format should be taken over from printer.
518 if (bOriChg || bPgSzChg)
519 {
520 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
521 VclMessageType::Question, VclButtonsType::YesNo,
522 aMsg));
523 if (RET_YES == xBox->run())
524 {
525 // Flags with changes for <SetPrinter(SfxPrinter*)> are maintained
526 nChangedFlags |= nNewOpt;
527 }
528 }
529
530 // Was the printer selection changed from Default to Specific
531 // or the other way around?
532 if ( (pNewPrinter->GetName() != pDocPrinter->GetName())
533 || (pDocPrinter->IsDefPrinter() != pNewPrinter->IsDefPrinter()) )
534 {
535 nChangedFlags |= SfxPrinterChangeFlags::PRINTER|SfxPrinterChangeFlags::JOBSETUP;
536 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
537 {
538 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
539 }
540
541 pDocPrinter = pNewPrinter;
542 }
543 else
544 {
545 // Compare extra options
546 if ( ! (pNewPrinter->GetOptions() == pDocPrinter->GetOptions()) )
547 {
548 // Option have changed
549 pDocPrinter->SetOptions( pNewPrinter->GetOptions() );
550 nChangedFlags |= SfxPrinterChangeFlags::OPTIONS;
551 }
552
553 // Compare JobSetups
554 JobSetup aNewJobSetup = pNewPrinter->GetJobSetup();
555 JobSetup aOldJobSetup = pDocPrinter->GetJobSetup();
556 if ( aNewJobSetup != aOldJobSetup )
557 {
558 nChangedFlags |= SfxPrinterChangeFlags::JOBSETUP;
559 }
560
561 // Keep old changed Printer.
562 pDocPrinter->SetPrinterProps( pNewPrinter );
563 pNewPrinter.disposeAndClear();
564 }
565
566 if ( SfxPrinterChangeFlags::NONE != nChangedFlags )
567 // SetPrinter will delete the old printer if it changes
568 SetPrinter( pDocPrinter, nChangedFlags );
569}
570
571void SfxViewShell::StartPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
572{
573 assert( !pImpl->m_xPrinterController )(static_cast <bool> (!pImpl->m_xPrinterController) ?
void (0) : __assert_fail ("!pImpl->m_xPrinterController",
"/home/maarten/src/libreoffice/core/sfx2/source/view/viewprn.cxx"
, 573, __extension__ __PRETTY_FUNCTION__))
;
574
575 // get the current selection; our controller should know it
576 Reference< frame::XController > xController( GetController() );
577 Reference< view::XSelectionSupplier > xSupplier( xController, UNO_QUERY );
578
579 Any aSelection;
580 if( xSupplier.is() )
581 aSelection = xSupplier->getSelection();
582 else
583 aSelection <<= GetObjectShell()->GetModel();
584 Any aComplete( makeAny( GetObjectShell()->GetModel() ) );
585 Any aViewProp( makeAny( xController ) );
586 VclPtr<Printer> aPrt;
587
588 const beans::PropertyValue* pVal = std::find_if(rProps.begin(), rProps.end(),
589 [](const beans::PropertyValue& rVal) { return rVal.Name == "PrinterName"; });
590 if (pVal != rProps.end())
591 {
592 OUString aPrinterName;
593 pVal->Value >>= aPrinterName;
594 aPrt.reset( VclPtr<Printer>::Create( aPrinterName ) );
595 }
596
597 std::shared_ptr<vcl::PrinterController> xNewController(std::make_shared<SfxPrinterController>(
598 aPrt,
599 aComplete,
600 aSelection,
601 aViewProp,
602 GetRenderable(),
603 bIsAPI,
604 bIsDirect,
605 this,
606 rProps
607 ));
608 pImpl->m_xPrinterController = xNewController;
609
610 SfxObjectShell *pObjShell = GetObjectShell();
611 xNewController->setValue( "JobName",
612 makeAny( pObjShell->GetTitle(1) ) );
613 xNewController->setPrinterModified( mbPrinterSettingsModified );
614}
615
616void SfxViewShell::ExecPrint( const uno::Sequence < beans::PropertyValue >& rProps, bool bIsAPI, bool bIsDirect )
617{
618 StartPrint( rProps, bIsAPI, bIsDirect );
619 // FIXME: job setup
620 SfxPrinter* pDocPrt = GetPrinter();
621 JobSetup aJobSetup = pDocPrt ? pDocPrt->GetJobSetup() : JobSetup();
622 Printer::PrintJob( GetPrinterController(), aJobSetup );
623}
624
625const std::shared_ptr< vcl::PrinterController >& SfxViewShell::GetPrinterController() const
626{
627 return pImpl->m_xPrinterController;
628}
629
630Printer* SfxViewShell::GetActivePrinter() const
631{
632 return pImpl->m_xPrinterController
633 ? pImpl->m_xPrinterController->getPrinter().get() : nullptr;
634}
635
636void SfxViewShell::ExecPrint_Impl( SfxRequest &rReq )
637{
638 sal_uInt16 nDialogRet = RET_CANCEL;
639 VclPtr<SfxPrinter> pPrinter;
640 bool bSilent = false;
641
642 // does the function have been called by the user interface or by an API call
643 bool bIsAPI = rReq.GetArgs() && rReq.GetArgs()->Count();
1
Assuming the condition is false
644 if ( bIsAPI
1.1
'bIsAPI' is false
1.1
'bIsAPI' is false
1.1
'bIsAPI' is false
1.1
'bIsAPI' is false
1.1
'bIsAPI' is false
)
2
Taking false branch
645 {
646 // the function have been called by the API
647
648 // Should it be visible on the user interface,
649 // should it launch popup dialogue ?
650 const SfxBoolItem* pSilentItem = rReq.GetArg<SfxBoolItem>(SID_SILENT(5000 + 528));
651 bSilent = pSilentItem && pSilentItem->GetValue();
652 }
653
654 // no help button in dialogs if called from the help window
655 // (pressing help button would exchange the current page inside the help
656 // document that is going to be printed!)
657 SfxMedium* pMedium = GetViewFrame()->GetObjectShell()->GetMedium();
658 std::shared_ptr<const SfxFilter> pFilter = pMedium ? pMedium->GetFilter() : nullptr;
3
Assuming 'pMedium' is null
4
'?' condition is false
659 bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == "writer_web_HTML_help" );
660
661 const sal_uInt16 nId = rReq.GetSlot();
662 switch( nId )
5
Control jumps to 'case 5302:' at line 760
663 {
664 case SID_PRINTDOC(5000 + 504): // display the printer selection and properties dialogue : File > Print...
665 case SID_PRINTDOCDIRECT(5000 + 509): // Print the document directly, without displaying the dialogue
666 {
667 SfxObjectShell* pDoc = GetObjectShell();
668
669 // derived class may decide to abort this
670 if( pDoc == nullptr || !pDoc->QuerySlotExecutable( nId ) )
671 {
672 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
673 return;
674 }
675
676 if ( !bSilent && pDoc->QueryHiddenInformation( HiddenWarningFact::WhenPrinting, nullptr ) != RET_YES )
677 return;
678
679 // should we print only the selection or the whole document
680 const SfxBoolItem* pSelectItem = rReq.GetArg<SfxBoolItem>(SID_SELECTIONTypedWhichId<SfxBoolItem>(5000 + 346));
681 bool bSelection = ( pSelectItem != nullptr && pSelectItem->GetValue() );
682 // detect non api call from writer ( that adds SID_SELECTION ) and reset bIsAPI
683 if ( pSelectItem && rReq.GetArgs()->Count() == 1 )
684 bIsAPI = false;
685
686 uno::Sequence < beans::PropertyValue > aProps;
687 if ( bIsAPI )
688 {
689 // supported properties:
690 // String PrinterName
691 // String FileName
692 // Int16 From
693 // Int16 To
694 // In16 Copies
695 // String RangeText
696 // bool Selection
697 // bool Asynchron
698 // bool Collate
699 // bool Silent
700
701 // the TransformItems function overwrite aProps
702 TransformItems( nId, *rReq.GetArgs(), aProps, GetInterface()->GetSlot(nId) );
703
704 for ( auto& rProp : aProps )
705 {
706 if ( rProp.Name == "Copies" )
707 {
708 rProp.Name = "CopyCount";
709 }
710 else if ( rProp.Name == "RangeText" )
711 {
712 rProp.Name = "Pages";
713 }
714 else if ( rProp.Name == "Asynchron" )
715 {
716 rProp.Name = "Wait";
717 bool bAsynchron = false;
718 rProp.Value >>= bAsynchron;
719 rProp.Value <<= !bAsynchron;
720 }
721 else if ( rProp.Name == "Silent" )
722 {
723 rProp.Name = "MonitorVisible";
724 bool bPrintSilent = false;
725 rProp.Value >>= bPrintSilent;
726 rProp.Value <<= !bPrintSilent;
727 }
728 }
729 }
730
731 // we will add the "PrintSelectionOnly" or "HideHelpButton" properties
732 // we have to increase the capacity of aProps
733 sal_Int32 nLen = aProps.getLength();
734 aProps.realloc( nLen + 1 );
735
736 // HACK: writer sets the SID_SELECTION item when printing directly and expects
737 // to get only the selection document in that case (see getSelectionObject)
738 // however it also reacts to the PrintContent property. We need this distinction here, too,
739 // else one of the combinations print / print direct and selection / all will not work.
740 // it would be better if writer handled this internally
741 if( nId == SID_PRINTDOCDIRECT(5000 + 509) )
742 {
743 aProps[nLen].Name = "PrintSelectionOnly";
744 aProps[nLen].Value <<= bSelection;
745 }
746 else // if nId == SID_PRINTDOC ; nothing to do with the previous HACK
747 {
748 // should the printer selection and properties dialogue display an help button
749 aProps[nLen].Name = "HideHelpButton";
750 aProps[nLen].Value <<= bPrintOnHelp;
751 }
752
753 ExecPrint( aProps, bIsAPI, (nId == SID_PRINTDOCDIRECT(5000 + 509)) );
754
755 // FIXME: Recording
756 rReq.Done();
757 break;
758 }
759
760 case SID_SETUPPRINTER(5000 + 302) : // display the printer settings dialogue : File > Printer Settings...
761 case SID_PRINTER_NAME(5000 + 322) : // only for recorded macros
762 {
763 // get printer and printer settings from the document
764 SfxPrinter *pDocPrinter = GetPrinter(true);
765
766 // look for printer in parameters
767 const SfxStringItem* pPrinterItem = rReq.GetArg<SfxStringItem>(SID_PRINTER_NAME(5000 + 322));
768 if ( pPrinterItem
5.1
'pPrinterItem' is null
5.1
'pPrinterItem' is null
5.1
'pPrinterItem' is null
5.1
'pPrinterItem' is null
5.1
'pPrinterItem' is null
)
6
Taking false branch
769 {
770 // use PrinterName parameter to create a printer
771 pPrinter = VclPtr<SfxPrinter>::Create( pDocPrinter->GetOptions().Clone(), pPrinterItem->GetValue() );
772
773 // if printer is unknown, it can't be used - now printer from document will be used
774 if ( !pPrinter->IsKnown() )
775 pPrinter.disposeAndClear();
776 }
777
778 if ( SID_PRINTER_NAME(5000 + 322) == nId )
7
Taking false branch
779 {
780 // just set a recorded printer name
781 if ( pPrinter )
782 SetPrinter( pPrinter, SfxPrinterChangeFlags::PRINTER );
783 return;
784 }
785
786 // no PrinterName parameter in ItemSet or the PrinterName points to an unknown printer
787 if ( !pPrinter )
8
Taking true branch
788 // use default printer from document
789 pPrinter = pDocPrinter;
790
791 if( !pPrinter || !pPrinter->IsValid() )
9
Taking false branch
792 {
793 // no valid printer either in ItemSet or at the document
794 if ( !bSilent )
795 {
796 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
797 VclMessageType::Warning, VclButtonsType::Ok,
798 SfxResId(STR_NODEFPRINTERreinterpret_cast<char const *>("STR_NODEFPRINTER" "\004"
u8"No default printer found.\nPlease choose a printer and try again."
)
)));
799 xBox->run();
800 }
801
802 rReq.SetReturnValue(SfxBoolItem(0,false));
803
804 break;
805 }
806
807 // FIXME: printer isn't used for printing anymore!
808 if( pPrinter->IsPrinting() )
10
Assuming the condition is false
11
Taking false branch
809 {
810 // if printer is busy, abort configuration
811 if ( !bSilent )
812 {
813 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
814 VclMessageType::Info, VclButtonsType::Ok,
815 SfxResId(STR_ERROR_PRINTER_BUSYreinterpret_cast<char const *>("STR_ERROR_PRINTER_BUSY"
"\004" u8"Printer busy")
)));
816 xBox->run();
817 }
818 rReq.SetReturnValue(SfxBoolItem(0,false));
819
820 return;
821 }
822
823 // if no arguments are given, retrieve them from a dialog
824 if ( !bIsAPI
11.1
'bIsAPI' is false
11.1
'bIsAPI' is false
11.1
'bIsAPI' is false
11.1
'bIsAPI' is false
11.1
'bIsAPI' is false
)
12
Taking true branch
825 {
826 // PrinterDialog needs a temporary printer
827 VclPtr<SfxPrinter> pDlgPrinter = pPrinter->Clone();
828
829 // execute PrinterSetupDialog
830 PrinterSetupDialog aPrintSetupDlg(GetFrameWeld());
831 std::unique_ptr<SfxDialogExecutor_Impl> pExecutor;
832
833 if (pImpl->m_bHasPrintOptions && HasPrintOptionsPage())
13
Assuming field 'm_bHasPrintOptions' is false
834 {
835 // additional controls for dialog
836 pExecutor.reset( new SfxDialogExecutor_Impl( this, aPrintSetupDlg ) );
837 if ( bPrintOnHelp )
838 pExecutor->DisableHelp();
839 aPrintSetupDlg.SetOptionsHdl( pExecutor->GetLink() );
840 }
841
842 aPrintSetupDlg.SetPrinter( pDlgPrinter );
14
Calling 'PrinterSetupDialog::SetPrinter'
23
Returning from 'PrinterSetupDialog::SetPrinter'
843 nDialogRet = aPrintSetupDlg.run();
844
845 if ( pExecutor && pExecutor->GetOptions() )
846 {
847 if ( nDialogRet == RET_OK )
848 // remark: have to be recorded if possible!
849 pDlgPrinter->SetOptions( *pExecutor->GetOptions() );
850 else
851 {
852 pPrinter->SetOptions( *pExecutor->GetOptions() );
853 SetPrinter( pPrinter, SfxPrinterChangeFlags::OPTIONS );
854 }
855 }
856
857 // no recording of PrinterSetup except printer name (is printer dependent)
858 rReq.Ignore();
859
860 if ( nDialogRet == RET_OK )
24
Assuming 'nDialogRet' is not equal to RET_OK
25
Taking false branch
861 {
862 if ( pPrinter->GetName() != pDlgPrinter->GetName() )
863 {
864 // user has changed the printer -> macro recording
865 SfxRequest aReq( GetViewFrame(), SID_PRINTER_NAME(5000 + 322) );
866 aReq.AppendItem( SfxStringItem( SID_PRINTER_NAME(5000 + 322), pDlgPrinter->GetName() ) );
867 aReq.Done();
868 }
869
870 // take the changes made in the dialog
871 SetPrinter_Impl( pDlgPrinter );
872
873 // forget new printer, it was taken over (as pPrinter) or deleted
874 pDlgPrinter = nullptr;
875 mbPrinterSettingsModified = true;
876 }
877 else
878 {
879 // PrinterDialog is used to transfer information on printing,
880 // so it will only be deleted here if dialog was cancelled
881 pDlgPrinter.disposeAndClear();
26
Calling 'VclPtr::disposeAndClear'
882 rReq.Ignore();
883 }
884 }
885 }
886 }
887}
888
889SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ )
890{
891 return nullptr;
892}
893
894sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/ )
895{
896 return 0;
897}
898
899std::unique_ptr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage(weld::Container*, weld::DialogController*, const SfxItemSet&)
900{
901 return nullptr;
902}
903
904bool SfxViewShell::HasPrintOptionsPage() const
905{
906 return false;
907}
908
909/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/svtools/prnsetup.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_SVTOOLS_PRNSETUP_HXX
21#define INCLUDED_SVTOOLS_PRNSETUP_HXX
22
23#include <svtools/svtdllapi.h>
24#include <vcl/print.hxx>
25#include <vcl/weld.hxx>
26#include <vcl/timer.hxx>
27
28class Printer;
29class QueueInfo;
30class VclSimpleEvent;
31
32class SVT_DLLPUBLIC__attribute__ ((visibility("default"))) PrinterSetupDialog final : public weld::GenericDialogController
33{
34private:
35 std::unique_ptr<weld::ComboBox> m_xLbName;
36 std::unique_ptr<weld::Button> m_xBtnProperties;
37 std::unique_ptr<weld::Button> m_xBtnOptions;
38 std::unique_ptr<weld::Label> m_xFiStatus;
39 std::unique_ptr<weld::Label> m_xFiType;
40 std::unique_ptr<weld::Label> m_xFiLocation;
41 std::unique_ptr<weld::Label> m_xFiComment;
42 AutoTimer maStatusTimer;
43 VclPtr<Printer> mpPrinter;
44 VclPtr<Printer> mpTempPrinter;
45
46 SVT_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplSetInfo();
47
48 DECL_DLLPRIVATE_LINK( ImplPropertiesHdl, weld::Button&, void )__attribute__ ((visibility("hidden"))) static void LinkStubImplPropertiesHdl
(void *, weld::Button&); __attribute__ ((visibility("hidden"
))) void ImplPropertiesHdl(weld::Button&)
;
49 DECL_DLLPRIVATE_LINK( ImplChangePrinterHdl, weld::ComboBox&, void )__attribute__ ((visibility("hidden"))) static void LinkStubImplChangePrinterHdl
(void *, weld::ComboBox&); __attribute__ ((visibility("hidden"
))) void ImplChangePrinterHdl(weld::ComboBox&)
;
50 DECL_DLLPRIVATE_LINK( ImplGetFocusHdl, weld::Widget&, void )__attribute__ ((visibility("hidden"))) static void LinkStubImplGetFocusHdl
(void *, weld::Widget&); __attribute__ ((visibility("hidden"
))) void ImplGetFocusHdl(weld::Widget&)
;
51 DECL_DLLPRIVATE_LINK( ImplStatusHdl, Timer*, void )__attribute__ ((visibility("hidden"))) static void LinkStubImplStatusHdl
(void *, Timer*); __attribute__ ((visibility("hidden"))) void
ImplStatusHdl(Timer*)
;
52 DECL_DLLPRIVATE_LINK( ImplDataChangedHdl, VclSimpleEvent&, void)__attribute__ ((visibility("hidden"))) static void LinkStubImplDataChangedHdl
(void *, VclSimpleEvent&); __attribute__ ((visibility("hidden"
))) void ImplDataChangedHdl(VclSimpleEvent&)
;
53
54public:
55 PrinterSetupDialog(weld::Window* pWindow);
56 virtual ~PrinterSetupDialog() override;
57
58 void SetPrinter( Printer* pNewPrinter ) { mpPrinter = pNewPrinter; }
15
Calling 'VclPtr::operator='
22
Returning from 'VclPtr::operator='
59 Printer* GetPrinter() const { return mpPrinter; }
60
61 virtual short run() override;
62
63 weld::Window* GetFrameWeld() const { return m_xDialog.get(); }
64
65 void SetOptionsHdl( const Link<weld::Button&,void>& rLink );
66};
67
68
69#define IMPL_PRINTDLG_STATUS_UPDATE15000 15000
70
71void ImplFillPrnDlgListBox( const Printer* pPrinter,
72 weld::ComboBox* pBox, weld::Button* pPropBtn );
73void ImplFreePrnDlgListBox( weld::ComboBox* pBox, bool bClear = true );
74Printer* ImplPrnDlgListBoxSelect( weld::ComboBox const * pBox, weld::Button* pPropBtn,
75 Printer const * pPrinter, Printer* pTempPrinter );
76Printer* ImplPrnDlgUpdatePrinter( Printer const * pPrinter, Printer* pTempPrinter );
77void ImplPrnDlgUpdateQueueInfo( weld::ComboBox const * pBox, QueueInfo& rInfo );
78OUString ImplPrnDlgGetStatusText( const QueueInfo& rInfo );
79
80#endif // INCLUDED_SVTOOLS_PRNSETUP_HXX
81
82/* 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);
16
Calling 'Reference::set'
21
Returning from 'Reference::set'
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 ;-)
27
Calling 'Reference::clear'
34
Returning; memory was released
205 if (aTmp.get()) {
35
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)
17
Assuming 'pBody' is non-null
18
Taking true branch
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
19
Assuming 'pOld' is null
20
Taking false branch
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
27.1
Field 'm_pBody' is non-null
27.1
Field 'm_pBody' is non-null
27.1
Field 'm_pBody' is non-null
27.1
Field 'm_pBody' is non-null
27.1
Field 'm_pBody' is non-null
)
28
Taking true branch
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
29
Calling 'VclReferenceBase::release'
33
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;
36
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)
30
Assuming the condition is true
31
Taking true branch
40 delete this;
32
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