File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 113, column 13 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <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 | ||||
58 | using namespace com::sun::star; | |||
59 | using namespace com::sun::star::uno; | |||
60 | ||||
61 | class 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 | ||||
80 | public: | |||
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 | ||||
100 | SfxPrinterController::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 | ||||
171 | void 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 | ||||
182 | const 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 | ||||
200 | Sequence< 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 | ||||
219 | int 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 | ||||
240 | Sequence< 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 | ||||
265 | void 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 | ||||
289 | void 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 | ||||
327 | void 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 | ||||
404 | namespace { | |||
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 | */ | |||
412 | class SfxDialogExecutor_Impl | |||
413 | { | |||
414 | private: | |||
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 | ||||
422 | public: | |||
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 | ||||
432 | SfxDialogExecutor_Impl::SfxDialogExecutor_Impl( SfxViewShell* pViewSh, PrinterSetupDialog& rParent ) : | |||
433 | ||||
434 | _pViewSh ( pViewSh ), | |||
435 | _rSetupParent ( rParent ), | |||
436 | _bHelpDisabled ( false ) | |||
437 | ||||
438 | { | |||
439 | } | |||
440 | ||||
441 | IMPL_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 | */ | |||
467 | void 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 | ||||
571 | void 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 | ||||
616 | void 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 | ||||
625 | const std::shared_ptr< vcl::PrinterController >& SfxViewShell::GetPrinterController() const | |||
626 | { | |||
627 | return pImpl->m_xPrinterController; | |||
628 | } | |||
629 | ||||
630 | Printer* SfxViewShell::GetActivePrinter() const | |||
631 | { | |||
632 | return pImpl->m_xPrinterController | |||
633 | ? pImpl->m_xPrinterController->getPrinter().get() : nullptr; | |||
634 | } | |||
635 | ||||
636 | void 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(); | |||
644 | if ( bIsAPI ) | |||
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; | |||
659 | bool bPrintOnHelp = ( pFilter && pFilter->GetFilterName() == "writer_web_HTML_help" ); | |||
660 | ||||
661 | const sal_uInt16 nId = rReq.GetSlot(); | |||
662 | switch( nId ) | |||
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 ) | |||
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 ) | |||
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 ) | |||
788 | // use default printer from document | |||
789 | pPrinter = pDocPrinter; | |||
790 | ||||
791 | if( !pPrinter || !pPrinter->IsValid() ) | |||
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() ) | |||
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 ) | |||
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()) | |||
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 ); | |||
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 ) | |||
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(); | |||
882 | rReq.Ignore(); | |||
883 | } | |||
884 | } | |||
885 | } | |||
886 | } | |||
887 | } | |||
888 | ||||
889 | SfxPrinter* SfxViewShell::GetPrinter( bool /*bCreate*/ ) | |||
890 | { | |||
891 | return nullptr; | |||
892 | } | |||
893 | ||||
894 | sal_uInt16 SfxViewShell::SetPrinter( SfxPrinter* /*pNewPrinter*/, SfxPrinterChangeFlags /*nDiffFlags*/ ) | |||
895 | { | |||
896 | return 0; | |||
897 | } | |||
898 | ||||
899 | std::unique_ptr<SfxTabPage> SfxViewShell::CreatePrintOptionsPage(weld::Container*, weld::DialogController*, const SfxItemSet&) | |||
900 | { | |||
901 | return nullptr; | |||
902 | } | |||
903 | ||||
904 | bool SfxViewShell::HasPrintOptionsPage() const | |||
905 | { | |||
906 | return false; | |||
907 | } | |||
908 | ||||
909 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||||||||
2 | /* | ||||||||||||
3 | * This file is part of the LibreOffice project. | ||||||||||||
4 | * | ||||||||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||||||||
8 | * | ||||||||||||
9 | * This file incorporates work covered by the following license notice: | ||||||||||||
10 | * | ||||||||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||||||||
13 | * with this work for additional information regarding copyright | ||||||||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||||||||
18 | */ | ||||||||||||
19 | |||||||||||||
20 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||||||
22 | |||||||||||||
23 | #include "sal/config.h" | ||||||||||||
24 | |||||||||||||
25 | #include <cassert> | ||||||||||||
26 | #include <cstddef> | ||||||||||||
27 | #include <functional> | ||||||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
29 | #include <type_traits> | ||||||||||||
30 | #endif | ||||||||||||
31 | |||||||||||||
32 | #include "sal/types.h" | ||||||||||||
33 | |||||||||||||
34 | namespace rtl | ||||||||||||
35 | { | ||||||||||||
36 | |||||||||||||
37 | /** Template reference class for reference type. | ||||||||||||
38 | */ | ||||||||||||
39 | template <class reference_type> | ||||||||||||
40 | class Reference | ||||||||||||
41 | { | ||||||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||||||
43 | */ | ||||||||||||
44 | reference_type * m_pBody; | ||||||||||||
45 | |||||||||||||
46 | |||||||||||||
47 | public: | ||||||||||||
48 | /** Constructor... | ||||||||||||
49 | */ | ||||||||||||
50 | Reference() | ||||||||||||
51 | : m_pBody (NULL__null) | ||||||||||||
52 | {} | ||||||||||||
53 | |||||||||||||
54 | |||||||||||||
55 | /** Constructor... | ||||||||||||
56 | */ | ||||||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||||||
58 | : m_pBody (pBody) | ||||||||||||
59 | { | ||||||||||||
60 | } | ||||||||||||
61 | |||||||||||||
62 | /** Constructor... | ||||||||||||
63 | */ | ||||||||||||
64 | Reference (reference_type * pBody) | ||||||||||||
65 | : m_pBody (pBody) | ||||||||||||
66 | { | ||||||||||||
67 | if (m_pBody) | ||||||||||||
68 | m_pBody->acquire(); | ||||||||||||
69 | } | ||||||||||||
70 | |||||||||||||
71 | /** Copy constructor... | ||||||||||||
72 | */ | ||||||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||||||
75 | { | ||||||||||||
76 | if (m_pBody) | ||||||||||||
77 | m_pBody->acquire(); | ||||||||||||
78 | } | ||||||||||||
79 | |||||||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
81 | /** Move constructor... | ||||||||||||
82 | */ | ||||||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||||||
85 | { | ||||||||||||
86 | handle.m_pBody = nullptr; | ||||||||||||
87 | } | ||||||||||||
88 | #endif | ||||||||||||
89 | |||||||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||||||
92 | |||||||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||||||
94 | |||||||||||||
95 | @param rRef another reference | ||||||||||||
96 | */ | ||||||||||||
97 | template< class derived_type > | ||||||||||||
98 | inline Reference( | ||||||||||||
99 | const Reference< derived_type > & rRef, | ||||||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||||||
101 | : m_pBody (rRef.get()) | ||||||||||||
102 | { | ||||||||||||
103 | if (m_pBody) | ||||||||||||
104 | m_pBody->acquire(); | ||||||||||||
105 | } | ||||||||||||
106 | #endif | ||||||||||||
107 | |||||||||||||
108 | /** Destructor... | ||||||||||||
109 | */ | ||||||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||||||
111 | { | ||||||||||||
112 | if (m_pBody
| ||||||||||||
113 | m_pBody->release(); | ||||||||||||
| |||||||||||||
114 | } | ||||||||||||
115 | |||||||||||||
116 | /** Set... | ||||||||||||
117 | Similar to assignment. | ||||||||||||
118 | */ | ||||||||||||
119 | Reference<reference_type> & | ||||||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||||||
121 | { | ||||||||||||
122 | if (pBody) | ||||||||||||
123 | pBody->acquire(); | ||||||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||||||
125 | m_pBody = pBody; | ||||||||||||
126 | if (pOld) | ||||||||||||
127 | pOld->release(); | ||||||||||||
128 | return *this; | ||||||||||||
129 | } | ||||||||||||
130 | |||||||||||||
131 | /** Assignment. | ||||||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||||||
133 | bind it to the body represented by the handle. | ||||||||||||
134 | */ | ||||||||||||
135 | Reference<reference_type> & | ||||||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||||||
137 | { | ||||||||||||
138 | return set( handle.m_pBody ); | ||||||||||||
139 | } | ||||||||||||
140 | |||||||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
142 | /** Assignment. | ||||||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||||||
144 | * bind it to the body represented by the handle, and | ||||||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||||||
146 | */ | ||||||||||||
147 | Reference<reference_type> & | ||||||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||||||
149 | { | ||||||||||||
150 | // self-movement guts ourself | ||||||||||||
151 | if (m_pBody) | ||||||||||||
152 | m_pBody->release(); | ||||||||||||
153 | m_pBody = handle.m_pBody; | ||||||||||||
154 | handle.m_pBody = nullptr; | ||||||||||||
155 | return *this; | ||||||||||||
156 | } | ||||||||||||
157 | #endif | ||||||||||||
158 | |||||||||||||
159 | /** Assignment... | ||||||||||||
160 | */ | ||||||||||||
161 | Reference<reference_type> & | ||||||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||||||
163 | { | ||||||||||||
164 | return set( pBody ); | ||||||||||||
165 | } | ||||||||||||
166 | |||||||||||||
167 | /** Unbind the body from this handle. | ||||||||||||
168 | Note that for a handle representing a large body, | ||||||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||||||
171 | since in the second case two large objects exist in memory | ||||||||||||
172 | (the old body and the new body). | ||||||||||||
173 | */ | ||||||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||||||
175 | { | ||||||||||||
176 | if (m_pBody) | ||||||||||||
177 | { | ||||||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||||||
179 | m_pBody = NULL__null; | ||||||||||||
180 | pOld->release(); | ||||||||||||
181 | } | ||||||||||||
182 | return *this; | ||||||||||||
183 | } | ||||||||||||
184 | |||||||||||||
185 | |||||||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||||||
188 | are the same. | ||||||||||||
189 | */ | ||||||||||||
190 | reference_type * SAL_CALL get() const | ||||||||||||
191 | { | ||||||||||||
192 | return m_pBody; | ||||||||||||
193 | } | ||||||||||||
194 | |||||||||||||
195 | |||||||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||||||
197 | */ | ||||||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||||||
199 | { | ||||||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
201 | return m_pBody; | ||||||||||||
202 | } | ||||||||||||
203 | |||||||||||||
204 | |||||||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||||||
206 | */ | ||||||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||||||
208 | { | ||||||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
210 | return *m_pBody; | ||||||||||||
211 | } | ||||||||||||
212 | |||||||||||||
213 | |||||||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||||||
215 | */ | ||||||||||||
216 | bool SAL_CALL is() const | ||||||||||||
217 | { | ||||||||||||
218 | return (m_pBody != NULL__null); | ||||||||||||
219 | } | ||||||||||||
220 | |||||||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||||||
223 | */ | ||||||||||||
224 | explicit operator bool() const | ||||||||||||
225 | { | ||||||||||||
226 | return is(); | ||||||||||||
227 | } | ||||||||||||
228 | #endif | ||||||||||||
229 | |||||||||||||
230 | /** Returns True if this points to pBody. | ||||||||||||
231 | */ | ||||||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||||||
233 | { | ||||||||||||
234 | return (m_pBody == pBody); | ||||||||||||
235 | } | ||||||||||||
236 | |||||||||||||
237 | |||||||||||||
238 | /** Returns True if handle points to the same body. | ||||||||||||
239 | */ | ||||||||||||
240 | bool | ||||||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||||||
242 | { | ||||||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||||||
244 | } | ||||||||||||
245 | |||||||||||||
246 | |||||||||||||
247 | /** Needed to place References into STL collection. | ||||||||||||
248 | */ | ||||||||||||
249 | bool | ||||||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||||||
251 | { | ||||||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||||||
253 | } | ||||||||||||
254 | |||||||||||||
255 | |||||||||||||
256 | /** Needed to place References into STL collection. | ||||||||||||
257 | */ | ||||||||||||
258 | bool | ||||||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||||||
260 | { | ||||||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||||||
262 | } | ||||||||||||
263 | |||||||||||||
264 | |||||||||||||
265 | /** Needed to place References into STL collection. | ||||||||||||
266 | */ | ||||||||||||
267 | bool | ||||||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||||||
269 | { | ||||||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||||||
271 | } | ||||||||||||
272 | }; | ||||||||||||
273 | |||||||||||||
274 | } // namespace rtl | ||||||||||||
275 | |||||||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
277 | namespace std | ||||||||||||
278 | { | ||||||||||||
279 | |||||||||||||
280 | /// @cond INTERNAL | ||||||||||||
281 | /** | ||||||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||||||
283 | |||||||||||||
284 | @since LibreOffice 6.3 | ||||||||||||
285 | */ | ||||||||||||
286 | template<typename T> | ||||||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||||||
288 | { | ||||||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||||||
290 | { return std::size_t(s.get()); } | ||||||||||||
291 | }; | ||||||||||||
292 | /// @endcond | ||||||||||||
293 | |||||||||||||
294 | } | ||||||||||||
295 | |||||||||||||
296 | #endif | ||||||||||||
297 | |||||||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||||||
299 | |||||||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |