Bug Summary

File:home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx
Warning:line 1201, 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 objserv.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/doc/objserv.cxx

/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.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 <config_features.h>
21
22#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
23#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
24#include <com/sun/star/util/CloseVetoException.hpp>
25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/beans/PropertyValue.hpp>
27#include <com/sun/star/document/XCmisDocument.hpp>
28#include <com/sun/star/drawing/LineStyle.hpp>
29#include <com/sun/star/lang/XServiceInfo.hpp>
30#include <com/sun/star/security/XCertificate.hpp>
31#include <com/sun/star/task/ErrorCodeIOException.hpp>
32#include <com/sun/star/task/InteractionHandler.hpp>
33#include <com/sun/star/task/XStatusIndicator.hpp>
34#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
35#include <comphelper/processfactory.hxx>
36#include <comphelper/servicehelper.hxx>
37#include <com/sun/star/security/CertificateValidity.hpp>
38#include <com/sun/star/drawing/XDrawView.hpp>
39
40#include <com/sun/star/security/DocumentSignatureInformation.hpp>
41#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
42#include <tools/diagnose_ex.h>
43#include <tools/urlobj.hxx>
44#include <svl/whiter.hxx>
45#include <svl/intitem.hxx>
46#include <svl/eitem.hxx>
47#include <svl/visitem.hxx>
48#include <svtools/sfxecode.hxx>
49#include <svtools/ehdl.hxx>
50#include <sal/log.hxx>
51#include <sfx2/app.hxx>
52
53#include <comphelper/string.hxx>
54#include <basic/sbxcore.hxx>
55#include <basic/sberrors.hxx>
56#include <unotools/moduleoptions.hxx>
57#include <unotools/saveopt.hxx>
58#include <svtools/DocumentToGraphicRenderer.hxx>
59#include <vcl/gdimtf.hxx>
60#include <vcl/svapp.hxx>
61#include <vcl/button.hxx>
62#include <vcl/weld.hxx>
63#include <comphelper/documentconstants.hxx>
64#include <comphelper/storagehelper.hxx>
65#include <tools/link.hxx>
66
67#include <asyncfunc.hxx>
68#include <sfx2/signaturestate.hxx>
69#include <sfx2/sfxresid.hxx>
70#include <sfx2/request.hxx>
71#include <sfx2/printer.hxx>
72#include <sfx2/viewsh.hxx>
73#include <sfx2/dinfdlg.hxx>
74#include <sfx2/docfilt.hxx>
75#include <sfx2/docfile.hxx>
76#include <sfx2/dispatch.hxx>
77#include <sfx2/objitem.hxx>
78#include <sfx2/objsh.hxx>
79#include <objshimp.hxx>
80#include <sfx2/module.hxx>
81#include <sfx2/viewfrm.hxx>
82#include <versdlg.hxx>
83#include <sfx2/strings.hrc>
84#include <sfx2/docfac.hxx>
85#include <sfx2/fcontnr.hxx>
86#include <sfx2/msgpool.hxx>
87#include <sfx2/objface.hxx>
88#include <checkin.hxx>
89#include <sfx2/infobar.hxx>
90#include <sfx2/sfxuno.hxx>
91#include <sfx2/sfxsids.hrc>
92#include <SfxRedactionHelper.hxx>
93
94#include <com/sun/star/util/XCloseable.hpp>
95#include <com/sun/star/document/XDocumentProperties.hpp>
96
97#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
98#include <com/sun/star/frame/XDesktop2.hpp>
99#include <com/sun/star/frame/Desktop.hpp>
100
101#include <guisaveas.hxx>
102#include <saveastemplatedlg.hxx>
103#include <memory>
104#include <cppuhelper/implbase.hxx>
105#include <unotools/ucbstreamhelper.hxx>
106#include <unotools/streamwrap.hxx>
107#include <comphelper/sequenceashashmap.hxx>
108
109#include <autoredactdialog.hxx>
110
111using namespace ::com::sun::star;
112using namespace ::com::sun::star::lang;
113using namespace ::com::sun::star::uno;
114using namespace ::com::sun::star::ui::dialogs;
115using namespace ::com::sun::star::awt;
116using namespace ::com::sun::star::container;
117using namespace ::com::sun::star::beans;
118using namespace ::com::sun::star::document;
119using namespace ::com::sun::star::security;
120using namespace ::com::sun::star::task;
121using namespace ::com::sun::star::graphic;
122
123#define ShellClass_SfxObjectShell
124#include <sfxslots.hxx>
125
126SFX_IMPL_SUPERCLASS_INTERFACE(SfxObjectShell, SfxShell)SfxInterface* SfxObjectShell::pInterface = nullptr; SfxInterface
* SfxObjectShell::GetStaticInterface() { if ( !pInterface ) {
pInterface = new SfxInterface( "SfxObjectShell", true, GetInterfaceId
(), SfxShell::GetStaticInterface(), aSfxObjectShellSlots_Impl
[0], sal_uInt16(sizeof(aSfxObjectShellSlots_Impl) / sizeof(SfxSlot
) ) ); InitInterface_Impl(); } return pInterface; } SfxInterface
* SfxObjectShell::GetInterface() const { return GetStaticInterface
(); } void SfxObjectShell::RegisterInterface(const SfxModule*
pMod) { GetStaticInterface()->Register(pMod); }
127
128void SfxObjectShell::InitInterface_Impl()
129{
130}
131
132namespace {
133
134class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper< css::util::XCloseListener >
135{
136 bool m_bGotOwnership;
137 bool m_bPreventClose;
138
139public:
140 SfxClosePreventer_Impl();
141
142 bool HasOwnership() const { return m_bGotOwnership; }
143
144 void SetPreventClose( bool bPrevent ) { m_bPreventClose = bPrevent; }
145
146 virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership ) override;
147
148 virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) override ;
149
150 virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) override ;
151
152} ;
153
154}
155
156SfxClosePreventer_Impl::SfxClosePreventer_Impl()
157: m_bGotOwnership( false )
158, m_bPreventClose( true )
159{
160}
161
162void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership )
163{
164 if ( m_bPreventClose )
165 {
166 if ( !m_bGotOwnership )
167 m_bGotOwnership = bDeliverOwnership;
168
169 throw util::CloseVetoException();
170 }
171}
172
173void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& )
174{}
175
176void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& )
177{}
178
179namespace {
180
181class SfxInstanceCloseGuard_Impl
182{
183 rtl::Reference<SfxClosePreventer_Impl> m_xPreventer;
184 uno::Reference< util::XCloseable > m_xCloseable;
185
186public:
187 SfxInstanceCloseGuard_Impl() {}
188
189 ~SfxInstanceCloseGuard_Impl();
190
191 bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable );
192};
193
194}
195
196bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable )
197{
198 bool bResult = false;
199
200 // do not allow reinit after the successful init
201 if ( xCloseable.is() && !m_xCloseable.is() )
202 {
203 try
204 {
205 m_xPreventer = new SfxClosePreventer_Impl();
206 xCloseable->addCloseListener( m_xPreventer.get() );
207 m_xCloseable = xCloseable;
208 bResult = true;
209 }
210 catch( uno::Exception& )
211 {
212 OSL_FAIL( "Could not register close listener!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "212" ": "), "%s", "Could not register close listener!")
; } } while (false)
;
213 }
214 }
215
216 return bResult;
217}
218
219SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl()
220{
221 if ( !m_xCloseable.is() || !m_xPreventer.is() )
222 return;
223
224 try
225 {
226 m_xCloseable->removeCloseListener( m_xPreventer.get() );
227 }
228 catch( uno::Exception& )
229 {
230 }
231
232 try
233 {
234 if ( m_xPreventer.is() )
235 {
236 m_xPreventer->SetPreventClose( false );
237
238 if ( m_xPreventer->HasOwnership() )
239 m_xCloseable->close( true ); // TODO: do it asynchronously
240 }
241 }
242 catch( uno::Exception& )
243 {
244 }
245}
246
247
248void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq)
249{
250 SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
251 if ( pFrame )
252 {
253 rReq.SetSlot( SID_PRINTDOC(5000 + 504) );
254 pFrame->GetViewShell()->ExecuteSlot(rReq);
255 }
256}
257
258
259void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet)
260{
261 bool bPrinting = false;
262 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
263 if ( pFrame )
264 {
265 SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter();
266 bPrinting = pPrinter && pPrinter->IsPrinting();
267 }
268 rSet.Put( SfxBoolItem( SID_PRINTOUT(5000 + 526), bPrinting ) );
269}
270
271bool SfxObjectShell::APISaveAs_Impl(const OUString& aFileName, SfxItemSet& rItemSet,
272 const css::uno::Sequence<css::beans::PropertyValue>& rArgs)
273{
274 bool bOk = false;
275
276 if ( GetMedium() )
277 {
278 OUString aFilterName;
279 const SfxStringItem* pFilterNameItem = rItemSet.GetItem<SfxStringItem>(SID_FILTER_NAME(5000 + 530), false);
280 if( pFilterNameItem )
281 {
282 aFilterName = pFilterNameItem->GetValue();
283 }
284 else
285 {
286 const SfxStringItem* pContentTypeItem = rItemSet.GetItem<SfxStringItem>(SID_CONTENTTYPE(5000 + 1541), false);
287 if ( pContentTypeItem )
288 {
289 std::shared_ptr<const SfxFilter> pFilter = SfxFilterMatcher( GetFactory().GetFactoryName() ).GetFilter4Mime( pContentTypeItem->GetValue(), SfxFilterFlags::EXPORT );
290 if ( pFilter )
291 aFilterName = pFilter->GetName();
292 }
293 }
294
295 // in case no filter defined use default one
296 if( aFilterName.isEmpty() )
297 {
298 std::shared_ptr<const SfxFilter> pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
299
300 DBG_ASSERT( pFilt, "No default filter!\n" )do { if (true && (!(pFilt))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "300" ": "), "%s", "No default filter!\n"); } } while (false
)
;
301 if( pFilt )
302 aFilterName = pFilt->GetFilterName();
303
304 rItemSet.Put(SfxStringItem(SID_FILTER_NAME(5000 + 530), aFilterName));
305 }
306
307
308 {
309 SfxObjectShellRef xLock( this ); // ???
310
311 // use the title that is provided in the media descriptor
312 const SfxStringItem* pDocTitleItem = rItemSet.GetItem<SfxStringItem>(SID_DOCINFO_TITLE(5000 + 557), false);
313 if ( pDocTitleItem )
314 getDocProperties()->setTitle( pDocTitleItem->GetValue() );
315
316 bOk = CommonSaveAs_Impl(INetURLObject(aFileName), aFilterName, rItemSet, rArgs);
317 }
318 }
319
320 return bOk;
321}
322
323void SfxObjectShell::CheckOut( )
324{
325 try
326 {
327 uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
328 xCmisDoc->checkOut( );
329
330 // Remove the info bar
331 SfxViewFrame* pViewFrame = GetFrame();
332 pViewFrame->RemoveInfoBar( "checkout" );
333 }
334 catch ( const uno::RuntimeException& e )
335 {
336 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrame()->GetWindow().GetFrameWeld(),
337 VclMessageType::Warning, VclButtonsType::Ok, e.Message));
338 xBox->run();
339 }
340}
341
342void SfxObjectShell::CancelCheckOut( )
343{
344 try
345 {
346 uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
347 xCmisDoc->cancelCheckOut( );
348
349 uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
350 if ( xModifiable.is( ) )
351 xModifiable->setModified( false );
352 }
353 catch ( const uno::RuntimeException& e )
354 {
355 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrame()->GetWindow().GetFrameWeld(),
356 VclMessageType::Warning, VclButtonsType::Ok, e.Message));
357 xBox->run();
358 }
359}
360
361void SfxObjectShell::CheckIn( )
362{
363 try
364 {
365 uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
366 // Pop up dialog to ask for comment and major
367 SfxCheckinDialog checkinDlg(GetFrame()->GetWindow().GetFrameWeld());
368 if (checkinDlg.run() == RET_OK)
369 {
370 xCmisDoc->checkIn(checkinDlg.IsMajor(), checkinDlg.GetComment());
371 uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
372 if ( xModifiable.is( ) )
373 xModifiable->setModified( false );
374 }
375 }
376 catch ( const uno::RuntimeException& e )
377 {
378 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrame()->GetWindow().GetFrameWeld(),
379 VclMessageType::Warning, VclButtonsType::Ok, e.Message));
380 xBox->run();
381 }
382}
383
384uno::Sequence< document::CmisVersion > SfxObjectShell::GetCmisVersions( ) const
385{
386 try
387 {
388 uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
389 return xCmisDoc->getAllVersions( );
390 }
391 catch ( const uno::RuntimeException& e )
392 {
393 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrame()->GetWindow().GetFrameWeld(),
394 VclMessageType::Warning, VclButtonsType::Ok, e.Message));
395 xBox->run();
396 }
397 return uno::Sequence< document::CmisVersion > ( );
398}
399
400bool SfxObjectShell::IsSignPDF() const
401{
402 if (pMedium && !pMedium->IsOriginallyReadOnly())
403 {
404 const std::shared_ptr<const SfxFilter>& pFilter = pMedium->GetFilter();
405 if (pFilter && pFilter->GetName() == "draw_pdf_import")
406 return true;
407 }
408
409 return false;
410}
411
412uno::Reference<security::XCertificate> SfxObjectShell::GetSignPDFCertificate() const
413{
414 uno::Reference<frame::XModel> xModel = GetBaseModel();
415 if (!xModel.is())
416 {
417 return uno::Reference<security::XCertificate>();
418 }
419
420 uno::Reference<drawing::XShapes> xShapes(xModel->getCurrentSelection(), uno::UNO_QUERY);
421 if (!xShapes.is() || xShapes->getCount() < 1)
422 {
423 return uno::Reference<security::XCertificate>();
424 }
425
426 uno::Reference<beans::XPropertySet> xShapeProps(xShapes->getByIndex(0), uno::UNO_QUERY);
427 if (!xShapeProps.is())
428 {
429 return uno::Reference<security::XCertificate>();
430 }
431
432 comphelper::SequenceAsHashMap aMap(xShapeProps->getPropertyValue("InteropGrabBag"));
433 auto it = aMap.find("SignatureCertificate");
434 if (it == aMap.end())
435 {
436 return uno::Reference<security::XCertificate>();
437 }
438
439 return uno::Reference<security::XCertificate>(it->second, uno::UNO_QUERY);
440}
441
442void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
443{
444 weld::Window* pDialogParent = rReq.GetFrameWeld();
445 if (!pDialogParent)
1
Assuming 'pDialogParent' is non-null
2
Taking false branch
446 {
447 SfxViewFrame* pFrame = GetFrame();
448 if (!pFrame)
449 pFrame = SfxViewFrame::GetFirst(this);
450 if (pFrame)
451 pDialogParent = pFrame->GetWindow().GetFrameWeld();
452 }
453
454 sal_uInt16 nId = rReq.GetSlot();
455
456 if( SID_SIGNATURE(5000 + 1643) == nId || SID_MACRO_SIGNATURE(5000 + 1704) == nId )
3
Assuming the condition is false
4
Assuming the condition is false
5
Taking false branch
457 {
458 if ( QueryHiddenInformation( HiddenWarningFact::WhenSigning, nullptr ) == RET_YES )
459 {
460 if (SID_SIGNATURE(5000 + 1643) == nId)
461 {
462 uno::Reference<security::XCertificate> xCertificate = GetSignPDFCertificate();
463 if (xCertificate.is())
464 {
465 SignDocumentContentUsingCertificate(xCertificate);
466
467 // Reload to show how the PDF actually looks like after signing. This also
468 // changes "finish signing" on the infobar back to "sign document" as a side
469 // effect.
470 SfxViewFrame* pFrame = GetFrame();
471 if (pFrame)
472 {
473 // Store current page before reload.
474 SfxAllItemSet aSet(SfxGetpApp()->GetPool());
475 uno::Reference<drawing::XDrawView> xController(
476 GetBaseModel()->getCurrentController(), uno::UNO_QUERY);
477 uno::Reference<beans::XPropertySet> xPage(xController->getCurrentPage(),
478 uno::UNO_QUERY);
479 sal_Int32 nPage{};
480 xPage->getPropertyValue("Number") >>= nPage;
481 if (nPage > 0)
482 {
483 // nPage is 1-based.
484 aSet.Put(SfxInt32Item(SID_PAGE_NUMBER(5000 + 655), nPage - 1));
485 }
486 SfxRequest aReq(SID_RELOAD(5000 + 508), SfxCallMode::SLOT, aSet);
487 pFrame->ExecReload_Impl(aReq);
488 }
489 }
490 else
491 {
492 SignDocumentContent(pDialogParent);
493 }
494 }
495 else
496 {
497 SignScriptingContent(pDialogParent);
498 }
499 }
500 return;
501 }
502
503 if ( !GetMedium() && nId != SID_CLOSEDOC(5000 + 503) )
6
Assuming the condition is false
504 {
505 rReq.Ignore();
506 return;
507 }
508
509 // this guard is created here to have it destruction at the end of the method
510 SfxInstanceCloseGuard_Impl aModelGuard;
511
512 bool bIsPDFExport = false;
513 bool bIsAutoRedact = false;
514 std::vector<std::pair<RedactionTarget*, OUString>> aRedactionTargets;
515 switch(nId)
7
Control jumps to 'case 6677:' at line 801
516 {
517 case SID_VERSION(5000 + 1583):
518 {
519 SfxViewFrame* pFrame = GetFrame();
520 if ( !pFrame )
521 pFrame = SfxViewFrame::GetFirst( this );
522 if ( !pFrame )
523 return;
524
525 if ( !IsOwnStorageFormat( *GetMedium() ) )
526 return;
527
528 SfxVersionDialog aDlg(pDialogParent, pFrame, IsSaveVersionOnClose());
529 aDlg.run();
530 SetSaveVersionOnClose(aDlg.IsSaveVersionOnClose());
531 rReq.Done();
532 return;
533 }
534
535 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
536 case SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535):
537 {
538 const SfxDocumentInfoItem* pDocInfItem = rReq.GetArg<SfxDocumentInfoItem>(SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535));
539 if ( pDocInfItem )
540 {
541 // parameter, e.g. from replayed macro
542 pDocInfItem->UpdateDocumentInfo(getDocProperties(), true);
543 SetUseUserData( pDocInfItem->IsUseUserData() );
544 SetUseThumbnailSave( pDocInfItem->IsUseThumbnailSave() );
545 }
546 else
547 {
548 // no argument containing DocInfo; check optional arguments
549 bool bReadOnly = IsReadOnly();
550 const SfxBoolItem* pROItem = rReq.GetArg<SfxBoolItem>(SID_DOC_READONLY(5000 + 590));
551 if ( pROItem )
552 // override readonly attribute of document
553 // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before
554 bReadOnly = pROItem->GetValue();
555
556 // URL for dialog
557 const OUString aURL( HasName() ? GetMedium()->GetName() : GetFactory().GetFactoryURL() );
558
559 Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
560 uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
561
562 SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(), aCmisProperties,
563 IsUseUserData(), IsUseThumbnailSave() );
564 if ( !GetSlotState( SID_DOCTEMPLATE(5000 + 538) ) )
565 // templates not supported
566 aDocInfoItem.SetTemplate(false);
567
568 SfxItemSet aSet(GetPool(), svl::Items<SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535), SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535), SID_DOC_READONLY(5000 + 590), SID_DOC_READONLY(5000 + 590),
569 SID_EXPLORER_PROPS_START(5000 + 1410), SID_EXPLORER_PROPS_START(5000 + 1410), SID_BASEURL(5000 + 1518), SID_BASEURL(5000 + 1518)>{} );
570 aSet.Put( aDocInfoItem );
571 aSet.Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), bReadOnly ) );
572 aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START(5000 + 1410), GetTitle() ) );
573 aSet.Put( SfxStringItem( SID_BASEURL(5000 + 1518), GetMedium()->GetBaseURL() ) );
574
575 // creating dialog is done via virtual method; application will
576 // add its own statistics page
577 std::shared_ptr<SfxRequest> pReq = std::make_shared<SfxRequest>(rReq);
578 std::shared_ptr<SfxDocumentInfoDialog> xDlg(CreateDocumentInfoDialog(rReq.GetFrameWeld(), aSet));
579 SfxTabDialogController::runAsync(xDlg, [this, xDlg, xCmisDoc, pReq](sal_Int32 nResult)
580 {
581 if (RET_OK == nResult)
582 {
583 const SfxDocumentInfoItem* pDocInfoItem = SfxItemSet::GetItem<SfxDocumentInfoItem>(xDlg->GetOutputItemSet(), SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535), false);
584 if ( pDocInfoItem )
585 {
586 // user has done some changes to DocumentInfo
587 pDocInfoItem->UpdateDocumentInfo(getDocProperties());
588 const uno::Sequence< document::CmisProperty >& aNewCmisProperties =
589 pDocInfoItem->GetCmisProperties( );
590 if ( aNewCmisProperties.hasElements( ) )
591 xCmisDoc->updateCmisProperties( aNewCmisProperties );
592 SetUseUserData( pDocInfoItem->IsUseUserData() );
593 SetUseThumbnailSave( pDocInfoItem-> IsUseThumbnailSave() );
594 // add data from dialog for possible recording purpose
595 pReq->AppendItem( SfxDocumentInfoItem( GetTitle(),
596 getDocProperties(), aNewCmisProperties, IsUseUserData(), IsUseThumbnailSave() ) );
597 }
598
599 css::uno::Reference< css::uno::XInterface > xInterface;
600 const SfxUnoAnyItem* pUnoAny = pReq->GetArg<SfxUnoAnyItem>(FN_PARAM_2((20000 + 1100)+61));
601 AsyncFunc* pAsyncFunc = pUnoAny && (pUnoAny->GetValue() >>= xInterface ) ?
602 comphelper::getUnoTunnelImplementation<AsyncFunc>(xInterface) : nullptr;
603 if (pAsyncFunc)
604 pAsyncFunc->Execute();
605
606 pReq->Done();
607 }
608 else
609 // nothing done; no recording
610 pReq->Ignore();
611 });
612
613 rReq.Ignore();
614 }
615
616 return;
617 }
618
619 case SID_AUTOREDACTDOC(5000 + 1736):
620 {
621 // Actual redaction takes place on a newly generated Draw document
622 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DRAW))
623 {
624 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
625 pDialogParent, VclMessageType::Warning, VclButtonsType::Ok,
626 SfxResId(STR_REDACTION_NO_DRAW_WARNINGreinterpret_cast<char const *>("STR_REDACTION_NO_DRAW_WARNING"
"\004" u8"Draw module is needed for redaction. Please make sure you have LibreOffice Draw installed and working correctly."
)
)));
627
628 xBox->run();
629
630 return;
631 }
632
633 SfxAutoRedactDialog aDlg(pDialogParent);
634 sal_Int16 nResult = aDlg.run();
635
636 if (nResult != RET_OK || !aDlg.hasTargets() || !aDlg.isValidState())
637 {
638 //Do nothing
639 return;
640 }
641
642 // else continue with normal redaction
643 bIsAutoRedact = true;
644 aDlg.getTargets(aRedactionTargets);
645
646 [[fallthrough]];
647 }
648
649 case SID_REDACTDOC(5000 + 1732):
650 {
651 css::uno::Reference<css::frame::XModel> xModel = GetModel();
652 if(!xModel.is())
653 return;
654
655 uno::Reference< lang::XComponent > xSourceDoc( xModel );
656
657 // Actual redaction takes place on a newly generated Draw document
658 if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::DRAW))
659 {
660 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
661 pDialogParent, VclMessageType::Warning, VclButtonsType::Ok,
662 SfxResId(STR_REDACTION_NO_DRAW_WARNINGreinterpret_cast<char const *>("STR_REDACTION_NO_DRAW_WARNING"
"\004" u8"Draw module is needed for redaction. Please make sure you have LibreOffice Draw installed and working correctly."
)
)));
663
664 xBox->run();
665
666 return;
667 }
668
669 DocumentToGraphicRenderer aRenderer(xSourceDoc, false);
670
671 // Get the page margins of the original doc
672 PageMargins aPageMargins = {-1, -1, -1, -1};
673 if (aRenderer.isWriter())
674 aPageMargins = SfxRedactionHelper::getPageMarginsForWriter(xModel);
675 else if (aRenderer.isCalc())
676 aPageMargins = SfxRedactionHelper::getPageMarginsForCalc(xModel);
677
678 sal_Int32 nPages = aRenderer.getPageCount();
679 std::vector< GDIMetaFile > aMetaFiles;
680 std::vector< ::Size > aPageSizes;
681
682 // Convert the pages of the document to gdimetafiles
683 SfxRedactionHelper::getPageMetaFilesFromDoc(aMetaFiles, aPageSizes, nPages, aRenderer);
684
685 // Create an empty Draw component.
686 uno::Reference<frame::XDesktop2> xDesktop = css::frame::Desktop::create(comphelper::getProcessComponentContext());
687 uno::Reference<lang::XComponent> xComponent = xDesktop->loadComponentFromURL("private:factory/sdraw", "_default", 0, {});
688
689 if (!xComponent.is())
690 {
691 SAL_WARN("sfx.doc", "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "691" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "691" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "691" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "SID_REDACTDOC: Failed to load new draw component. loadComponentFromURL returned an empty reference."
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "691" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
692
693 return;
694 }
695
696 // Add the doc pages to the new draw document
697 SfxRedactionHelper::addPagesToDraw(xComponent, nPages, aMetaFiles, aPageSizes, aPageMargins, aRedactionTargets, bIsAutoRedact);
698
699 // Show the Redaction toolbar
700 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
701 if (!pViewFrame)
702 return;
703 SfxRedactionHelper::showRedactionToolbar(pViewFrame);
704
705 return;
706 }
707
708 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
709 case SID_DIRECTEXPORTDOCASPDF(5000 + 1674):
710 {
711 uno::Reference< lang::XComponent > xComponent( GetCurrentComponent(), uno::UNO_QUERY );
712 if (!xComponent.is())
713 return;
714
715 uno::Reference< lang::XServiceInfo > xServiceInfo( xComponent, uno::UNO_QUERY);
716
717 // Redaction finalization takes place in Draw
718 if ( xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument")
719 && SfxRedactionHelper::isRedactMode(rReq) )
720 {
721 OUString sRedactionStyle(SfxRedactionHelper::getStringParam(rReq, SID_REDACTION_STYLE(5000 + 1734)));
722
723 // Access the draw pages
724 uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY);
725 uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
726
727 sal_Int32 nPageCount = xDrawPages->getCount();
728 for (sal_Int32 nPageNum = 0; nPageNum < nPageCount; ++nPageNum)
729 {
730 // Get the page
731 uno::Reference< drawing::XDrawPage > xPage( xDrawPages->getByIndex( nPageNum ), uno::UNO_QUERY );
732
733 if (!xPage.is())
734 continue;
735
736 // Go through all shapes
737 sal_Int32 nShapeCount = xPage->getCount();
738 for (sal_Int32 nShapeNum = 0; nShapeNum < nShapeCount; ++nShapeNum)
739 {
740 uno::Reference< drawing::XShape > xCurrShape(xPage->getByIndex(nShapeNum), uno::UNO_QUERY);
741 if (!xCurrShape.is())
742 continue;
743
744 uno::Reference< beans::XPropertySet > xPropSet(xCurrShape, uno::UNO_QUERY);
745 if (!xPropSet.is())
746 continue;
747
748 uno::Reference< beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
749 if (!xInfo.is())
750 continue;
751
752 OUString sShapeName;
753 if (xInfo->hasPropertyByName("Name"))
754 {
755 uno::Any aAnyShapeName = xPropSet->getPropertyValue("Name");
756 aAnyShapeName >>= sShapeName;
757 }
758 else
759 continue;
760
761 // Rectangle redaction
762 if (sShapeName == "RectangleRedactionShape"
763 && xInfo->hasPropertyByName("FillTransparence") && xInfo->hasPropertyByName("FillColor"))
764 {
765 xPropSet->setPropertyValue("FillTransparence", css::uno::makeAny(static_cast<sal_Int16>(0)));
766 if (sRedactionStyle == "White")
767 {
768 xPropSet->setPropertyValue("FillColor", css::uno::makeAny(COL_WHITE));
769 xPropSet->setPropertyValue("LineStyle", css::uno::makeAny(css::drawing::LineStyle::LineStyle_SOLID));
770 xPropSet->setPropertyValue("LineColor", css::uno::makeAny(COL_BLACK));
771 }
772 else
773 {
774 xPropSet->setPropertyValue("FillColor", css::uno::makeAny(COL_BLACK));
775 xPropSet->setPropertyValue("LineStyle", css::uno::makeAny(css::drawing::LineStyle::LineStyle_NONE));
776 }
777 }
778 // Freeform redaction
779 else if (sShapeName == "FreeformRedactionShape"
780 && xInfo->hasPropertyByName("LineTransparence") && xInfo->hasPropertyByName("LineColor"))
781 {
782 xPropSet->setPropertyValue("LineTransparence", css::uno::makeAny(static_cast<sal_Int16>(0)));
783
784 if (sRedactionStyle == "White")
785 {
786 xPropSet->setPropertyValue("LineColor", css::uno::makeAny(COL_WHITE));
787 }
788 else
789 {
790 xPropSet->setPropertyValue("LineColor", css::uno::makeAny(COL_BLACK));
791 }
792 }
793 }
794 }
795 }
796 }
797 [[fallthrough]];
798 case SID_EXPORTDOCASPDF(5000 + 1673):
799 bIsPDFExport = true;
800 [[fallthrough]];
801 case SID_EXPORTDOCASEPUB(5000 + 1677):
802 case SID_DIRECTEXPORTDOCASEPUB(5000 + 1678):
803 case SID_EXPORTDOC(5000 + 829):
804 case SID_SAVEASDOC(5000 + 502):
805 case SID_SAVEASREMOTE(5000 + 516):
806 case SID_SAVEDOC(5000 + 505):
807 {
808 // derived class may decide to abort this
809 if( !QuerySlotExecutable( nId ) )
8
Assuming the condition is false
9
Taking false branch
810 {
811 rReq.SetReturnValue( SfxBoolItem( 0, false ) );
812 return;
813 }
814
815 //!! detailed analysis of an error code
816 SfxObjectShellRef xLock( this );
817
818 // the model can not be closed till the end of this method
819 // if somebody tries to close it during this time the model will be closed
820 // at the end of the method
821 aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
822
823 ErrCode nErrorCode = ERRCODE_NONEErrCode(0);
824
825 // by default versions should be preserved always except in case of an explicit
826 // SaveAs via GUI, so the flag must be set accordingly
827 pImpl->bPreserveVersions = (nId == SID_SAVEDOC(5000 + 505));
828 try
829 {
830 SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC3, GetTitle() ); // ???
831
832 if ( nId == SID_SAVEASDOC(5000 + 502) || nId == SID_SAVEASREMOTE(5000 + 516) )
10
Taking false branch
833 {
834 // in case of plugin mode the SaveAs operation means SaveTo
835 const SfxBoolItem* pViewOnlyItem = SfxItemSet::GetItem<SfxBoolItem>(GetMedium()->GetItemSet(), SID_VIEWONLY(5000 + 1682), false);
836 if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
837 rReq.AppendItem( SfxBoolItem( SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546), true ) );
838 }
839
840 // TODO/LATER: do the following GUI related actions in standalone method
841
842 // Introduce a status indicator for GUI operation
843 const SfxUnoAnyItem* pStatusIndicatorItem = rReq.GetArg<SfxUnoAnyItem>(SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597));
844 if ( !pStatusIndicatorItem
10.1
'pStatusIndicatorItem' is non-null
10.1
'pStatusIndicatorItem' is non-null
)
11
Taking false branch
845 {
846 // get statusindicator
847 uno::Reference< task::XStatusIndicator > xStatusIndicator;
848 uno::Reference < frame::XController > xCtrl( GetModel()->getCurrentController() );
849 if ( xCtrl.is() )
850 {
851 uno::Reference< task::XStatusIndicatorFactory > xStatFactory( xCtrl->getFrame(), uno::UNO_QUERY );
852 if( xStatFactory.is() )
853 xStatusIndicator = xStatFactory->createStatusIndicator();
854 }
855
856 OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!" )do { if (true && (!(xStatusIndicator.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "856" ": "), "%s", "Can not retrieve default status indicator!"
); } } while (false)
;
857
858 if ( xStatusIndicator.is() )
859 {
860 SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL(5000 + 1597), uno::makeAny( xStatusIndicator ) );
861
862 if ( nId == SID_SAVEDOC(5000 + 505) )
863 {
864 // in case of saving it is not possible to transport the parameters from here
865 // but it is not clear here whether the saving will be done or saveAs operation
866 GetMedium()->GetItemSet()->Put( aStatIndItem );
867 }
868
869 rReq.AppendItem( aStatIndItem );
870 }
871 }
872 else if ( nId == SID_SAVEDOC(5000 + 505) )
12
Taking false branch
873 {
874 // in case of saving it is not possible to transport the parameters from here
875 // but it is not clear here whether the saving will be done or saveAs operation
876 GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem );
877 }
878
879 // Introduce an interaction handler for GUI operation
880 const SfxUnoAnyItem* pInteractionHandlerItem = rReq.GetArg<SfxUnoAnyItem>(SID_INTERACTIONHANDLER(5000 + 1675));
881 if ( !pInteractionHandlerItem
12.1
'pInteractionHandlerItem' is non-null
12.1
'pInteractionHandlerItem' is non-null
)
13
Taking false branch
882 {
883 uno::Reference<css::awt::XWindow> xParentWindow;
884 uno::Reference<frame::XController> xCtrl(GetModel()->getCurrentController());
885 if (xCtrl.is())
886 xParentWindow = xCtrl->getFrame()->getContainerWindow();
887
888 uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
889
890 uno::Reference< task::XInteractionHandler2 > xInteract(
891 task::InteractionHandler::createWithParent(xContext, xParentWindow) );
892
893 SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER(5000 + 1675), uno::makeAny( xInteract ) );
894 if ( nId == SID_SAVEDOC(5000 + 505) )
895 {
896 // in case of saving it is not possible to transport the parameters from here
897 // but it is not clear here whether the saving will be done or saveAs operation
898 GetMedium()->GetItemSet()->Put( aInteractionItem );
899 }
900
901 rReq.AppendItem( aInteractionItem );
902 }
903 else if ( nId == SID_SAVEDOC(5000 + 505) )
14
Taking false branch
904 {
905 // in case of saving it is not possible to transport the parameters from here
906 // but it is not clear here whether the saving will be done or saveAs operation
907 GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem );
908 }
909
910
911 const SfxStringItem* pOldPasswordItem = SfxItemSet::GetItem<SfxStringItem>(GetMedium()->GetItemSet(), SID_PASSWORD(((((10000 + 1499) + 1) + 499) + 1) + 36), false);
912 const SfxUnoAnyItem* pOldEncryptionDataItem = SfxItemSet::GetItem<SfxUnoAnyItem>(GetMedium()->GetItemSet(), SID_ENCRYPTIONDATA(5000 + 1722), false);
913 bool bPreselectPassword = (pOldPasswordItem
14.1
'pOldPasswordItem' is null
14.1
'pOldPasswordItem' is null
&& pOldEncryptionDataItem);
914
915 uno::Sequence< beans::PropertyValue > aDispatchArgs;
916 if ( rReq.GetArgs() )
15
Taking true branch
917 TransformItems( nId,
918 *rReq.GetArgs(),
919 aDispatchArgs );
920
921 bool bForceSaveAs = nId == SID_SAVEDOC(5000 + 505) && IsReadOnlyMedium();
922 const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( bForceSaveAs
15.1
'bForceSaveAs' is false
15.1
'bForceSaveAs' is false
? SID_SAVEASDOC(5000 + 502) : nId );
16
'?' condition is false
923 if ( !pSlot )
17
Assuming 'pSlot' is non-null
18
Taking false branch
924 throw uno::Exception("no slot", nullptr);
925
926 SfxStoringHelper aHelper;
927
928 if ( QueryHiddenInformation( bIsPDFExport
18.1
'bIsPDFExport' is false
18.1
'bIsPDFExport' is false
? HiddenWarningFact::WhenCreatingPDF : HiddenWarningFact::WhenSaving, nullptr ) != RET_YES
)
19
'?' condition is false
20
Assuming the condition is false
21
Taking false branch
929 {
930 // the user has decided not to store the document
931 throw task::ErrorCodeIOException(
932 "SfxObjectShell::ExecFile_Impl: ERRCODE_IO_ABORT",
933 uno::Reference< uno::XInterface >(), sal_uInt32(ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 )));
934 }
935
936 aHelper.GUIStoreModel( GetModel(),
937 OUString::createFromAscii( pSlot->GetUnoName() ),
938 aDispatchArgs,
939 bPreselectPassword,
940 GetDocumentSignatureState() );
941
942
943 // merge aDispatchArgs to the request
944 SfxAllItemSet aResultParams( GetPool() );
945 TransformParameters( nId,
946 aDispatchArgs,
947 aResultParams );
948 rReq.SetArgs( aResultParams );
949
950 // the StoreAsURL/StoreToURL method have called this method with false
951 // so it has to be restored to true here since it is a call from GUI
952 GetMedium()->SetUpdatePickList( true );
953
954 // TODO: in future it must be done in following way
955 // if document is opened from GUI, it immediately appears in the picklist
956 // if the document is a new one then it appears in the picklist immediately
957 // after SaveAs operation triggered from GUI
958 }
959 catch( const task::ErrorCodeIOException& aErrorEx )
960 {
961 TOOLS_WARN_EXCEPTION( "sfx.doc", "Fatal IO error during save")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Fatal IO error during save"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "961" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Fatal IO error during save" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Fatal IO error during save" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "961" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Fatal IO error during save" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "961" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Fatal IO error during save" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"Fatal IO error during save" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "961" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
962 nErrorCode = ErrCode(aErrorEx.ErrCode);
963 }
964 catch( Exception& )
965 {
966 nErrorCode = ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 );
967 }
968
969 // by default versions should be preserved always except in case of an explicit
970 // SaveAs via GUI, so the flag must be reset to guarantee this
971 pImpl->bPreserveVersions = true;
972 ErrCode lErr=GetErrorCode();
973
974 if ( !lErr && nErrorCode )
22
Taking false branch
975 lErr = nErrorCode;
976
977 if ( lErr && nErrorCode == ERRCODE_NONEErrCode(0) )
23
Taking false branch
978 {
979 const SfxBoolItem* pWarnItem = rReq.GetArg<SfxBoolItem>(SID_FAIL_ON_WARNING(5000 + 1646));
980 if ( pWarnItem && pWarnItem->GetValue() )
981 nErrorCode = lErr;
982 }
983
984 // may be nErrorCode should be shown in future
985 if ( lErr != ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ) )
24
Taking true branch
986 {
987 SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC3,GetTitle());
988 ErrorHandler::HandleError(lErr, pDialogParent);
989 }
990
991 if (nId == SID_DIRECTEXPORTDOCASPDF(5000 + 1674) &&
992 SfxRedactionHelper::isRedactMode(rReq))
993 {
994 // Return the finalized redaction shapes back to normal (gray & transparent)
995 uno::Reference< lang::XComponent > xComponent( GetCurrentComponent(), uno::UNO_QUERY );
996 if (!xComponent.is())
997 return;
998
999 uno::Reference< lang::XServiceInfo > xServiceInfo( xComponent, uno::UNO_QUERY);
1000
1001 // Redaction finalization takes place in Draw
1002 if ( xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument") )
1003 {
1004 // Access the draw pages
1005 uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(xComponent, uno::UNO_QUERY);
1006 uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
1007
1008 sal_Int32 nPageCount = xDrawPages->getCount();
1009 for (sal_Int32 nPageNum = 0; nPageNum < nPageCount; ++nPageNum)
1010 {
1011 // Get the page
1012 uno::Reference< drawing::XDrawPage > xPage( xDrawPages->getByIndex( nPageNum ), uno::UNO_QUERY );
1013
1014 if (!xPage.is())
1015 continue;
1016
1017 // Go through all shapes
1018 sal_Int32 nShapeCount = xPage->getCount();
1019 for (sal_Int32 nShapeNum = 0; nShapeNum < nShapeCount; ++nShapeNum)
1020 {
1021 uno::Reference< drawing::XShape > xCurrShape(xPage->getByIndex(nShapeNum), uno::UNO_QUERY);
1022 if (!xCurrShape.is())
1023 continue;
1024
1025 uno::Reference< beans::XPropertySet > xPropSet(xCurrShape, uno::UNO_QUERY);
1026 if (!xPropSet.is())
1027 continue;
1028
1029 uno::Reference< beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
1030 if (!xInfo.is())
1031 continue;
1032
1033 // Not a shape we converted?
1034 if (!xInfo->hasPropertyByName("Name"))
1035 continue;
1036
1037 OUString sShapeName;
1038 if (xInfo->hasPropertyByName("Name"))
1039 {
1040 uno::Any aAnyShapeName = xPropSet->getPropertyValue("Name");
1041 aAnyShapeName >>= sShapeName;
1042 }
1043 else
1044 continue;
1045
1046 // Rectangle redaction
1047 if (sShapeName == "RectangleRedactionShape"
1048 && xInfo->hasPropertyByName("FillTransparence") && xInfo->hasPropertyByName("FillColor"))
1049 {
1050 xPropSet->setPropertyValue("FillTransparence", css::uno::makeAny(static_cast<sal_Int16>(50)));
1051 xPropSet->setPropertyValue("FillColor", css::uno::makeAny(COL_GRAY7));
1052 xPropSet->setPropertyValue("LineStyle", css::uno::makeAny(css::drawing::LineStyle::LineStyle_NONE));
1053
1054 }
1055 // Freeform redaction
1056 else if (sShapeName == "FreeformRedactionShape")
1057 {
1058 xPropSet->setPropertyValue("LineTransparence", css::uno::makeAny(static_cast<sal_Int16>(50)));
1059 xPropSet->setPropertyValue("LineColor", css::uno::makeAny(COL_GRAY7));
1060 }
1061 }
1062 }
1063
1064
1065 }
1066 }
1067
1068 if ( nId == SID_EXPORTDOCASPDF(5000 + 1673) )
25
Taking false branch
1069 {
1070 // This function is used by the SendMail function that needs information if an export
1071 // file was written or not. This could be due to cancellation of the export
1072 // or due to an error. So IO abort must be handled like an error!
1073 nErrorCode = ( lErr != ERRCODE_IO_ABORTErrCode( ErrCodeArea::Io, ErrCodeClass::Abort, 27 ) ) && ( nErrorCode == ERRCODE_NONEErrCode(0) ) ? nErrorCode : lErr;
1074 }
1075
1076 if ( ( nId == SID_SAVEASDOC(5000 + 502) || nId == SID_SAVEASREMOTE(5000 + 516) ) && nErrorCode == ERRCODE_NONEErrCode(0) )
26
Taking false branch
1077 {
1078 const SfxBoolItem* saveTo = rReq.GetArg<SfxBoolItem>(SID_SAVETOTypedWhichId<SfxBoolItem>(5000 + 1546));
1079 if (saveTo == nullptr || !saveTo->GetValue())
1080 {
1081 SfxViewFrame *pFrame = GetFrame();
1082 if (pFrame)
1083 pFrame->RemoveInfoBar("readonly");
1084 SetReadOnlyUI(false);
1085 }
1086 }
1087
1088 rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONEErrCode(0) ) );
1089
1090 ResetError();
1091
1092 Invalidate();
1093 break;
27
Calling '~SvRef'
37
Returning from '~SvRef'
38
Execution continues on line 1200
1094 }
1095
1096 case SID_SAVEACOPY(5000 + 999):
1097 {
1098 SfxAllItemSet aArgs( GetPool() );
1099 aArgs.Put( SfxBoolItem( SID_SAVEACOPYITEM(5000 + 998), true ) );
1100 SfxRequest aSaveACopyReq( SID_EXPORTDOC(5000 + 829), SfxCallMode::API, aArgs );
1101 ExecFile_Impl( aSaveACopyReq );
1102 if ( !aSaveACopyReq.IsDone() )
1103 {
1104 rReq.Ignore();
1105 return;
1106 }
1107 break;
1108 }
1109
1110 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1111
1112 case SID_CLOSEDOC(5000 + 503):
1113 {
1114 // Evaluate Parameter
1115 const SfxBoolItem* pSaveItem = rReq.GetArg<SfxBoolItem>(SID_CLOSEDOC_SAVE(5000 + 1));
1116 const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_CLOSEDOC_FILENAME(5000 + 2));
1117 if ( pSaveItem )
1118 {
1119 if ( pSaveItem->GetValue() )
1120 {
1121 if ( !pNameItem )
1122 {
1123#if HAVE_FEATURE_SCRIPTING1
1124 SbxBase::SetError( ERRCODE_BASIC_WRONG_ARGSErrCode( ErrCodeArea::Sbx, ErrCodeClass::Sbx, 28) );
1125#endif
1126 rReq.Ignore();
1127 return;
1128 }
1129 SfxAllItemSet aArgs( GetPool() );
1130 SfxStringItem aTmpItem( SID_FILE_NAME(5000 + 507), pNameItem->GetValue() );
1131 aArgs.Put( aTmpItem, aTmpItem.Which() );
1132 SfxRequest aSaveAsReq( SID_SAVEASDOC(5000 + 502), SfxCallMode::API, aArgs );
1133 ExecFile_Impl( aSaveAsReq );
1134 if ( !aSaveAsReq.IsDone() )
1135 {
1136 rReq.Ignore();
1137 return;
1138 }
1139 }
1140 else
1141 SetModified(false);
1142 }
1143
1144 // Cancelled by the user?
1145 if (!PrepareClose())
1146 {
1147 rReq.SetReturnValue( SfxBoolItem(0, false) );
1148 rReq.Done();
1149 return;
1150 }
1151
1152 SetModified( false );
1153 ErrCode lErr = GetErrorCode();
1154 ErrorHandler::HandleError(lErr, pDialogParent);
1155
1156 rReq.SetReturnValue( SfxBoolItem(0, true) );
1157 rReq.Done();
1158 rReq.ReleaseArgs(); // because the pool is destroyed in Close
1159 DoClose();
1160 return;
1161 }
1162
1163 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1164 case SID_DOCTEMPLATE(5000 + 538):
1165 {
1166 // save as document templates
1167 SfxSaveAsTemplateDialog aDlg(pDialogParent, GetModel());
1168 (void)aDlg.run();
1169 break;
1170 }
1171
1172 case SID_CHECKOUT(5000 + 512):
1173 {
1174 CheckOut( );
1175 break;
1176 }
1177 case SID_CANCELCHECKOUT(5000 + 513):
1178 {
1179 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
1180 VclMessageType::Question, VclButtonsType::YesNo, SfxResId(STR_QUERY_CANCELCHECKOUTreinterpret_cast<char const *>("STR_QUERY_CANCELCHECKOUT"
"\004" u8"This will discard all changes on the server since check-out.\nDo you want to proceed?"
)
)));
1181 if (xBox->run() == RET_YES)
1182 {
1183 CancelCheckOut( );
1184
1185 // Reload the document as we may still have local changes
1186 SfxViewFrame *pFrame = GetFrame();
1187 if ( pFrame )
1188 pFrame->GetDispatcher()->Execute(SID_RELOAD(5000 + 508));
1189 }
1190 break;
1191 }
1192 case SID_CHECKIN(5000 + 514):
1193 {
1194 CheckIn( );
1195 break;
1196 }
1197 }
1198
1199 // Prevent entry in the Pick-lists
1200 if ( rReq.IsAPI() )
39
Assuming the condition is true
40
Taking true branch
1201 GetMedium()->SetUpdatePickList( false );
41
Use of memory after it is freed
1202
1203 // Ignore()-branches have already returned
1204 rReq.Done();
1205}
1206
1207
1208void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
1209{
1210 SfxWhichIter aIter( rSet );
1211
1212 for ( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
1213 {
1214 switch ( nWhich )
1215 {
1216 case SID_DOCTEMPLATE(5000 + 538) :
1217 {
1218 if ( isExportLocked())
1219 rSet.DisableItem( nWhich );
1220 break;
1221 }
1222
1223 case SID_CHECKOUT(5000 + 512):
1224 {
1225 bool bShow = false;
1226 Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
1227 const uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
1228
1229 if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
1230 {
1231 // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
1232 bool bIsGoogleFile = false;
1233 bool bCheckedOut = false;
1234 for ( const auto& rCmisProperty : aCmisProperties )
1235 {
1236 if ( rCmisProperty.Id == "cmis:isVersionSeriesCheckedOut" )
1237 {
1238 uno::Sequence< sal_Bool > bTmp;
1239 rCmisProperty.Value >>= bTmp;
1240 bCheckedOut = bTmp[0];
1241 }
1242 // using title to know if it's a Google Drive file
1243 // maybe there's a safer way.
1244 if ( rCmisProperty.Name == "title" )
1245 bIsGoogleFile = true;
1246 }
1247 bShow = !bCheckedOut && !bIsGoogleFile;
1248 }
1249
1250 if ( !bShow )
1251 {
1252 rSet.DisableItem( nWhich );
1253 rSet.Put( SfxVisibilityItem( nWhich, false ) );
1254 }
1255 }
1256 break;
1257
1258 case SID_CANCELCHECKOUT(5000 + 513):
1259 case SID_CHECKIN(5000 + 514):
1260 {
1261 bool bShow = false;
1262 Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
1263 uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties( );
1264
1265 if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
1266 {
1267 // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
1268 bool bCheckedOut = false;
1269 auto pProp = std::find_if(aCmisProperties.begin(), aCmisProperties.end(),
1270 [](const document::CmisProperty& rProp) { return rProp.Id == "cmis:isVersionSeriesCheckedOut"; });
1271 if (pProp != aCmisProperties.end())
1272 {
1273 uno::Sequence< sal_Bool > bTmp;
1274 pProp->Value >>= bTmp;
1275 bCheckedOut = bTmp[0];
1276 }
1277 bShow = bCheckedOut;
1278 }
1279
1280 if ( !bShow )
1281 {
1282 rSet.DisableItem( nWhich );
1283 rSet.Put( SfxVisibilityItem( nWhich, false ) );
1284 }
1285 }
1286 break;
1287
1288 case SID_VERSION(5000 + 1583):
1289 {
1290 SfxObjectShell *pDoc = this;
1291 SfxViewFrame* pFrame = GetFrame();
1292 if ( !pFrame )
1293 pFrame = SfxViewFrame::GetFirst( this );
1294
1295 if ( !pFrame || !pDoc->HasName() ||
1296 !IsOwnStorageFormat( *pDoc->GetMedium() ) )
1297 rSet.DisableItem( nWhich );
1298 break;
1299 }
1300 case SID_SAVEDOC(5000 + 505):
1301 {
1302 if ( IsReadOnly() || isSaveLocked())
1303 {
1304 rSet.DisableItem(nWhich);
1305 break;
1306 }
1307 rSet.Put(SfxStringItem(nWhich, SfxResId(STR_SAVEDOCreinterpret_cast<char const *>("STR_SAVEDOC" "\004" u8"~Save"
)
)));
1308 }
1309 break;
1310
1311 case SID_DOCINFOTypedWhichId<SfxDocumentInfoItem>(5000 + 535):
1312 break;
1313
1314 case SID_CLOSEDOC(5000 + 503):
1315 {
1316 rSet.Put(SfxStringItem(nWhich, SfxResId(STR_CLOSEDOCreinterpret_cast<char const *>("STR_CLOSEDOC" "\004" u8"~Close"
)
)));
1317 break;
1318 }
1319
1320 case SID_SAVEASDOC(5000 + 502):
1321 {
1322 if (!(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT)
1323 || isExportLocked())
1324 {
1325 rSet.DisableItem( nWhich );
1326 break;
1327 }
1328 if ( /*!pCombinedFilters ||*/ !GetMedium() )
1329 rSet.DisableItem( nWhich );
1330 else
1331 rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEASDOCreinterpret_cast<char const *>("STR_SAVEASDOC" "\004" u8"Save ~As..."
)
) ) );
1332 break;
1333 }
1334
1335 case SID_SAVEACOPY(5000 + 999):
1336 {
1337 if (!(pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT) || isExportLocked())
1338 {
1339 rSet.DisableItem( nWhich );
1340 break;
1341 }
1342 if ( /*!pCombinedFilters ||*/ !GetMedium() )
1343 rSet.DisableItem( nWhich );
1344 else
1345 rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEACOPYreinterpret_cast<char const *>("STR_SAVEACOPY" "\004" u8"Save a Copy..."
)
) ) );
1346 break;
1347 }
1348
1349 case SID_EXPORTDOC(5000 + 829):
1350 case SID_EXPORTDOCASPDF(5000 + 1673):
1351 case SID_DIRECTEXPORTDOCASPDF(5000 + 1674):
1352 case SID_EXPORTDOCASEPUB(5000 + 1677):
1353 case SID_DIRECTEXPORTDOCASEPUB(5000 + 1678):
1354 case SID_REDACTDOC(5000 + 1732):
1355 case SID_AUTOREDACTDOC(5000 + 1736):
1356 case SID_SAVEASREMOTE(5000 + 516):
1357 {
1358 if (isExportLocked())
1359 rSet.DisableItem( nWhich );
1360 break;
1361 }
1362
1363 case SID_DOC_MODIFIED(5000 + 584):
1364 {
1365 rSet.Put( SfxBoolItem( SID_DOC_MODIFIED(5000 + 584), IsModified() ) );
1366 break;
1367 }
1368
1369 case SID_MODIFIEDTypedWhichId<SfxBoolItem>(27000 +89):
1370 {
1371 rSet.Put( SfxBoolItem( SID_MODIFIEDTypedWhichId<SfxBoolItem>(27000 +89), IsModified() ) );
1372 break;
1373 }
1374
1375 case SID_DOCINFO_TITLE(5000 + 557):
1376 {
1377 rSet.Put( SfxStringItem(
1378 SID_DOCINFO_TITLE(5000 + 557), getDocProperties()->getTitle() ) );
1379 break;
1380 }
1381 case SID_FILE_NAME(5000 + 507):
1382 {
1383 if( GetMedium() && HasName() )
1384 rSet.Put( SfxStringItem(
1385 SID_FILE_NAME(5000 + 507), GetMedium()->GetName() ) );
1386 break;
1387 }
1388 case SID_SIGNATURE(5000 + 1643):
1389 {
1390 SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
1391 if ( pFrame )
1392 {
1393 SignatureState eState = GetDocumentSignatureState();
1394 InfobarType aInfobarType(InfobarType::INFO);
1395 OUString sMessage("");
1396
1397 switch (eState)
1398 {
1399 case SignatureState::BROKEN:
1400 sMessage = SfxResId(STR_SIGNATURE_BROKENreinterpret_cast<char const *>("STR_SIGNATURE_BROKEN" "\004"
u8"This document has an invalid signature.")
);
1401 aInfobarType = InfobarType::DANGER;
1402 break;
1403 case SignatureState::INVALID:
1404 sMessage = SfxResId(STR_SIGNATURE_INVALIDreinterpret_cast<char const *>("STR_SIGNATURE_INVALID" "\004"
u8"The signature was valid, but the document has been modified"
)
);
1405 // Warning only, I've tried Danger and it looked too scary
1406 aInfobarType = InfobarType::WARNING;
1407 break;
1408 case SignatureState::NOTVALIDATED:
1409 sMessage = SfxResId(STR_SIGNATURE_NOTVALIDATEDreinterpret_cast<char const *>("STR_SIGNATURE_NOTVALIDATED"
"\004" u8"At least one signature has problems: the certificate could not be validated."
)
);
1410 aInfobarType = InfobarType::WARNING;
1411 break;
1412 case SignatureState::PARTIAL_OK:
1413 sMessage = SfxResId(STR_SIGNATURE_PARTIAL_OKreinterpret_cast<char const *>("STR_SIGNATURE_PARTIAL_OK"
"\004" u8"At least one signature has problems: the document is only partially signed."
)
);
1414 aInfobarType = InfobarType::WARNING;
1415 break;
1416 case SignatureState::OK:
1417 sMessage = SfxResId(STR_SIGNATURE_OKreinterpret_cast<char const *>("STR_SIGNATURE_OK" "\004"
u8"This document is digitally signed and the signature is valid."
)
);
1418 aInfobarType = InfobarType::INFO;
1419 break;
1420 case SignatureState::NOTVALIDATED_PARTIAL_OK:
1421 sMessage = SfxResId(STR_SIGNATURE_NOTVALIDATED_PARTIAL_OKreinterpret_cast<char const *>("STR_SIGNATURE_NOTVALIDATED_PARTIAL_OK"
"\004" u8"The certificate could not be validated and the document is only partially signed."
)
);
1422 aInfobarType = InfobarType::WARNING;
1423 break;
1424 //FIXME SignatureState::Unknown, own message?
1425 default:
1426 break;
1427 }
1428
1429 // new info bar
1430 if ( !pFrame->HasInfoBarWithID("signature") )
1431 {
1432 if ( !sMessage.isEmpty() )
1433 {
1434 auto pInfoBar = pFrame->AppendInfoBar("signature", "", sMessage, aInfobarType);
1435 if (pInfoBar == nullptr || pInfoBar->IsDisposed())
1436 return;
1437 weld::Button& rBtn = pInfoBar->addButton();
1438 rBtn.set_label(SfxResId(STR_SIGNATURE_SHOWreinterpret_cast<char const *>("STR_SIGNATURE_SHOW" "\004"
u8"Show Signatures")
));
1439 rBtn.connect_clicked(LINK(this, SfxObjectShell, SignDocumentHandler)::tools::detail::makeLink( ::tools::detail::castTo<SfxObjectShell
*>(this), &SfxObjectShell::LinkStubSignDocumentHandler
)
);
1440 }
1441 }
1442 else // info bar exists already
1443 {
1444 if ( eState == SignatureState::NOSIGNATURES )
1445 pFrame->RemoveInfoBar("signature");
1446 else
1447 pFrame->UpdateInfoBar("signature", "", sMessage, aInfobarType);
1448 }
1449 }
1450
1451 rSet.Put( SfxUInt16Item( SID_SIGNATURE(5000 + 1643), static_cast<sal_uInt16>(GetDocumentSignatureState()) ) );
1452 break;
1453 }
1454 case SID_MACRO_SIGNATURE(5000 + 1704):
1455 {
1456 // the slot makes sense only if there is a macro in the document
1457 if ( pImpl->documentStorageHasMacros() || pImpl->aMacroMode.hasMacroLibrary() )
1458 rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE(5000 + 1704), static_cast<sal_uInt16>(GetScriptingSignatureState()) ) );
1459 else
1460 rSet.DisableItem( nWhich );
1461 break;
1462 }
1463 case SID_DOC_REPAIR(5000 + 510):
1464 {
1465 SfxUndoManager* pIUndoMgr = GetUndoManager();
1466 if (pIUndoMgr)
1467 rSet.Put( SfxBoolItem(nWhich, pIUndoMgr->IsEmptyActions()) );
1468 else
1469 rSet.DisableItem( nWhich );
1470 break;
1471 }
1472 }
1473 }
1474}
1475
1476IMPL_LINK_NOARG(SfxObjectShell, SignDocumentHandler, weld::Button&, void)void SfxObjectShell::LinkStubSignDocumentHandler(void * instance
, weld::Button& data) { return static_cast<SfxObjectShell
*>(instance)->SignDocumentHandler(data); } void SfxObjectShell
::SignDocumentHandler(__attribute__ ((unused)) weld::Button&
)
1477{
1478 GetDispatcher()->Execute(SID_SIGNATURE(5000 + 1643));
1479}
1480
1481void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq)
1482{
1483 switch ( rReq.GetSlot() )
1484 {
1485 case SID_MODIFIEDTypedWhichId<SfxBoolItem>(27000 +89):
1486 {
1487 SetModified( rReq.GetArgs()->Get(SID_MODIFIEDTypedWhichId<SfxBoolItem>(27000 +89)).GetValue() );
1488 rReq.Done();
1489 break;
1490 }
1491
1492 case SID_DOCTITLETypedWhichId<SfxStringItem>(5000 + 583):
1493 SetTitle( rReq.GetArgs()->Get(SID_DOCTITLETypedWhichId<SfxStringItem>(5000 + 583)).GetValue() );
1494 rReq.Done();
1495 break;
1496
1497 case SID_DOCINFO_AUTHOR(5000 + 593) :
1498 getDocProperties()->setAuthor( static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue() );
1499 break;
1500
1501 case SID_DOCINFO_COMMENTS(5000 + 592) :
1502 getDocProperties()->setDescription( static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue() );
1503 break;
1504
1505 case SID_DOCINFO_KEYWORDS(5000 + 591) :
1506 {
1507 const OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1508 getDocProperties()->setKeywords(
1509 ::comphelper::string::convertCommaSeparated(aStr) );
1510 break;
1511 }
1512 }
1513}
1514
1515
1516void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet)
1517{
1518 SfxWhichIter aIter(rSet);
1519 for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
1520 {
1521 switch ( nSID )
1522 {
1523 case SID_DOCINFO_AUTHOR(5000 + 593) :
1524 {
1525 rSet.Put( SfxStringItem( nSID,
1526 getDocProperties()->getAuthor() ) );
1527 break;
1528 }
1529
1530 case SID_DOCINFO_COMMENTS(5000 + 592) :
1531 {
1532 rSet.Put( SfxStringItem( nSID,
1533 getDocProperties()->getDescription()) );
1534 break;
1535 }
1536
1537 case SID_DOCINFO_KEYWORDS(5000 + 591) :
1538 {
1539 rSet.Put( SfxStringItem( nSID, ::comphelper::string::
1540 convertCommaSeparated(getDocProperties()->getKeywords())) );
1541 break;
1542 }
1543
1544 case SID_DOCPATH(5000 + 582):
1545 {
1546 OSL_FAIL( "Not supported anymore!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1546" ": "), "%s", "Not supported anymore!"); } } while
(false)
;
1547 break;
1548 }
1549
1550 case SID_DOCFULLNAME(5000 + 581):
1551 {
1552 rSet.Put( SfxStringItem( SID_DOCFULLNAME(5000 + 581), GetTitle(SFX_TITLE_FULLNAME2) ) );
1553 break;
1554 }
1555
1556 case SID_DOCTITLETypedWhichId<SfxStringItem>(5000 + 583):
1557 {
1558 rSet.Put( SfxStringItem( SID_DOCTITLETypedWhichId<SfxStringItem>(5000 + 583), GetTitle() ) );
1559 break;
1560 }
1561
1562 case SID_DOC_READONLY(5000 + 590):
1563 {
1564 rSet.Put( SfxBoolItem( SID_DOC_READONLY(5000 + 590), IsReadOnly() ) );
1565 break;
1566 }
1567
1568 case SID_DOC_SAVED(5000 + 599):
1569 {
1570 rSet.Put( SfxBoolItem( SID_DOC_SAVED(5000 + 599), !IsModified() ) );
1571 break;
1572 }
1573
1574 case SID_CLOSING(5000 +1539):
1575 {
1576 rSet.Put( SfxBoolItem( SID_CLOSING(5000 +1539), false ) );
1577 break;
1578 }
1579
1580 case SID_DOC_LOADING(5000 + 585):
1581 rSet.Put( SfxBoolItem( nSID, ! ( pImpl->nLoadedFlags & SfxLoadedFlags::MAINDOCUMENT ) ) );
1582 break;
1583
1584 case SID_IMG_LOADING(5000 + 586):
1585 rSet.Put( SfxBoolItem( nSID, ! ( pImpl->nLoadedFlags & SfxLoadedFlags::IMAGES ) ) );
1586 break;
1587 }
1588 }
1589}
1590
1591
1592void SfxObjectShell::ExecView_Impl(SfxRequest &rReq)
1593{
1594 switch ( rReq.GetSlot() )
1595 {
1596 case SID_ACTIVATE(5000 + 525):
1597 {
1598 SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this );
1599 if ( pFrame )
1600 pFrame->GetFrame().Appear();
1601 rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) );
1602 rReq.Done();
1603 break;
1604 }
1605 }
1606}
1607
1608
1609void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/)
1610{
1611}
1612
1613/// Does this ZIP storage have a signature stream?
1614static bool HasSignatureStream(const uno::Reference<embed::XStorage>& xStorage)
1615{
1616 if (!xStorage.is())
1617 return false;
1618
1619 if (xStorage->hasByName("META-INF"))
1620 {
1621 // ODF case.
1622 try
1623 {
1624 uno::Reference<embed::XStorage> xMetaInf
1625 = xStorage->openStorageElement("META-INF", embed::ElementModes::READ);
1626 if (xMetaInf.is())
1627 {
1628 return xMetaInf->hasByName("documentsignatures.xml")
1629 || xMetaInf->hasByName("macrosignatures.xml")
1630 || xMetaInf->hasByName("packagesignatures.xml");
1631 }
1632 }
1633 catch (const css::io::IOException&)
1634 {
1635 TOOLS_WARN_EXCEPTION("sfx.doc", "HasSignatureStream: failed to open META-INF")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "HasSignatureStream: failed to open META-INF"
<< " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1635" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "HasSignatureStream: failed to open META-INF"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "HasSignatureStream: failed to open META-INF" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1635" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "HasSignatureStream: failed to open META-INF" <<
" " << exceptionToString(tools_warn_exception)) == 1) {
::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc")
, ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1635" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "HasSignatureStream: failed to open META-INF"
<< " " << exceptionToString(tools_warn_exception
)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "HasSignatureStream: failed to open META-INF" <<
" " << exceptionToString(tools_warn_exception); ::sal::
detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1635" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1636 }
1637 }
1638
1639 // OOXML case.
1640 return xStorage->hasByName("_xmlsignatures");
1641}
1642
1643uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::GetDocumentSignatureInformation( bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner )
1644{
1645 uno::Sequence< security::DocumentSignatureInformation > aResult;
1646 uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
1647
1648 bool bSupportsSigning = GetMedium() && GetMedium()->GetFilter() && GetMedium()->GetFilter()->GetSupportsSigning();
1649 if (GetMedium() && !GetMedium()->GetName().isEmpty() && ((IsOwnStorageFormat(*GetMedium()) && GetMedium()->GetStorage().is()) || bSupportsSigning))
1650 {
1651 try
1652 {
1653 if ( !xLocSigner.is() )
1654 {
1655 OUString aVersion;
1656 try
1657 {
1658 uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1659 xPropSet->getPropertyValue("Version") >>= aVersion;
1660 }
1661 catch( uno::Exception& )
1662 {
1663 }
1664
1665 xLocSigner.set( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1666
1667 }
1668
1669 if ( bScriptingContent )
1670 aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1671 uno::Reference< io::XInputStream >() );
1672 else
1673 {
1674 if (GetMedium()->GetStorage(false).is())
1675 {
1676 // Something ZIP-based.
1677 // Only call into xmlsecurity if we see a signature stream,
1678 // as libxmlsec init is expensive.
1679 if (HasSignatureStream(GetMedium()->GetZipStorageToSign_Impl()))
1680 aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1681 uno::Reference< io::XInputStream >() );
1682 }
1683 else
1684 {
1685 // Not ZIP-based, e.g. PDF.
1686
1687 // Create temp file if needed.
1688 GetMedium()->CreateTempFile(/*bReplace=*/false);
1689
1690 std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(GetMedium()->GetName(), StreamMode::READ));
1691 uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
1692 uno::Reference<io::XInputStream> xInputStream(xStream, uno::UNO_QUERY);
1693 aResult = xLocSigner->verifyDocumentContentSignatures(uno::Reference<embed::XStorage>(), xInputStream);
1694 }
1695 }
1696 }
1697 catch( css::uno::Exception& )
1698 {
1699 }
1700 }
1701
1702 return aResult;
1703}
1704
1705SignatureState SfxObjectShell::ImplGetSignatureState( bool bScriptingContent )
1706{
1707 SignatureState* pState = bScriptingContent ? &pImpl->nScriptingSignatureState : &pImpl->nDocumentSignatureState;
1708
1709 if ( *pState == SignatureState::UNKNOWN )
1710 {
1711 *pState = SignatureState::NOSIGNATURES;
1712
1713 uno::Sequence< security::DocumentSignatureInformation > aInfos = GetDocumentSignatureInformation( bScriptingContent );
1714 *pState = DocumentSignatures::getSignatureState(aInfos);
1715 }
1716
1717 if ( *pState == SignatureState::OK || *pState == SignatureState::NOTVALIDATED
1718 || *pState == SignatureState::PARTIAL_OK)
1719 {
1720 if ( IsModified() )
1721 *pState = SignatureState::INVALID;
1722 }
1723
1724 return *pState;
1725}
1726
1727bool SfxObjectShell::PrepareForSigning(weld::Window* pDialogParent)
1728{
1729 // check whether the document is signed
1730 ImplGetSignatureState(); // document signature
1731 if (GetMedium() && GetMedium()->GetFilter() && GetMedium()->GetFilter()->IsOwnFormat())
1732 ImplGetSignatureState( true ); // script signature
1733 bool bHasSign = ( pImpl->nScriptingSignatureState != SignatureState::NOSIGNATURES || pImpl->nDocumentSignatureState != SignatureState::NOSIGNATURES );
1734
1735 // the target ODF version on saving (only valid when signing ODF of course)
1736 SvtSaveOptions aSaveOpt;
1737 SvtSaveOptions::ODFSaneDefaultVersion nVersion = aSaveOpt.GetODFSaneDefaultVersion();
1738
1739 // the document is not new and is not modified
1740 OUString aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
1741
1742 if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
1743 || (GetMedium()->GetFilter()->IsOwnFormat() && aODFVersion.compareTo(ODFVER_012_TEXT"1.2") < 0 && !bHasSign))
1744 {
1745 // the document might need saving ( new, modified or in ODF1.1 format without signature )
1746
1747 if (nVersion >= SvtSaveOptions::ODFSVER_012)
1748 {
1749 OUString sQuestion(bHasSign ? SfxResId(STR_XMLSEC_QUERY_SAVESIGNEDBEFORESIGNreinterpret_cast<char const *>("STR_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN"
"\004" u8"The document has to be saved before it can be signed. Saving the document removes all present signatures.\nDo you want to save the document?"
)
) : SfxResId(RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGNreinterpret_cast<char const *>("RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGN"
"\004" u8"The document has to be saved before it can be signed.\nDo you want to save the document?"
)
));
1750 std::unique_ptr<weld::MessageDialog> xQuestion(Application::CreateMessageDialog(pDialogParent,
1751 VclMessageType::Question, VclButtonsType::YesNo, sQuestion));
1752
1753
1754 if (xQuestion->run() == RET_YES)
1755 {
1756 sal_uInt16 nId = SID_SAVEDOC(5000 + 505);
1757 if ( !GetMedium() || GetMedium()->GetName().isEmpty() )
1758 nId = SID_SAVEASDOC(5000 + 502);
1759 SfxRequest aSaveRequest( nId, SfxCallMode::SLOT, GetPool() );
1760 //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
1761 SetModified();
1762 ExecFile_Impl( aSaveRequest );
1763
1764 // Check if it is stored a format which supports signing
1765 if (GetMedium() && GetMedium()->GetFilter() && !GetMedium()->GetName().isEmpty()
1766 && ((!GetMedium()->GetFilter()->IsOwnFormat()
1767 && !GetMedium()->GetFilter()->GetSupportsSigning())
1768 || (GetMedium()->GetFilter()->IsOwnFormat()
1769 && !GetMedium()->HasStorage_Impl())))
1770 {
1771 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
1772 pDialogParent, VclMessageType::Info, VclButtonsType::Ok,
1773 SfxResId(STR_INFO_WRONGDOCFORMATreinterpret_cast<char const *>("STR_INFO_WRONGDOCFORMAT"
"\004" u8"This document must be saved in OpenDocument file format before it can be digitally signed."
)
)));
1774
1775 xBox->run();
1776 return false;
1777 }
1778 }
1779 else
1780 {
1781 // When the document is modified then we must not show the
1782 // digital signatures dialog
1783 // If we have come here then the user denied to save.
1784 if (!bHasSign)
1785 return false;
1786 }
1787 }
1788 else
1789 {
1790 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pDialogParent,
1791 VclMessageType::Warning, VclButtonsType::Ok, SfxResId(STR_XMLSEC_ODF12_EXPECTEDreinterpret_cast<char const *>("STR_XMLSEC_ODF12_EXPECTED"
"\004" u8"The document format version is set to ODF 1.1 (OpenOffice.org 2.x) in Tools-Options-Load/Save-General. Signing documents requires ODF 1.2 (OpenOffice.org 3.x)."
)
)));
1792 xBox->run();
1793 return false;
1794 }
1795
1796 if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
1797 return false;
1798 }
1799
1800 // the document is not modified currently, so it can not become modified after signing
1801 pImpl->m_bAllowModifiedBackAfterSigning = false;
1802 if ( IsEnableSetModified() )
1803 {
1804 EnableSetModified( false );
1805 pImpl->m_bAllowModifiedBackAfterSigning = true;
1806 }
1807
1808 // we have to store to the original document, the original medium should be closed for this time
1809 if ( ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1810 {
1811 GetMedium()->CloseAndRelease();
1812 return true;
1813 }
1814 return false;
1815}
1816
1817void SfxObjectShell::RecheckSignature(bool bAlsoRecheckScriptingSignature)
1818{
1819 if (bAlsoRecheckScriptingSignature)
1820 pImpl->nScriptingSignatureState = SignatureState::UNKNOWN; // Re-Check
1821
1822 pImpl->nDocumentSignatureState = SignatureState::UNKNOWN; // Re-Check
1823
1824 Invalidate(SID_SIGNATURE(5000 + 1643));
1825 Invalidate(SID_MACRO_SIGNATURE(5000 + 1704));
1826 Broadcast(SfxHint(SfxHintId::TitleChanged));
1827}
1828
1829void SfxObjectShell::AfterSigning(bool bSignSuccess, bool bSignScriptingContent)
1830{
1831 pImpl->m_bSavingForSigning = true;
1832 DoSaveCompleted( GetMedium() );
1833 pImpl->m_bSavingForSigning = false;
1834
1835 if ( bSignSuccess )
1836 RecheckSignature(bSignScriptingContent);
1837
1838 if ( pImpl->m_bAllowModifiedBackAfterSigning )
1839 EnableSetModified();
1840}
1841
1842bool SfxObjectShell::CheckIsReadonly(bool bSignScriptingContent)
1843{
1844 if (GetMedium()->IsOriginallyReadOnly())
1845 {
1846 // If the file is physically read-only, we just show the existing signatures
1847 try
1848 {
1849 OUString aODFVersion(
1850 comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
1851 uno::Reference<security::XDocumentDigitalSignatures> xSigner(
1852 security::DocumentDigitalSignatures::createWithVersionAndValidSignature(
1853 comphelper::getProcessComponentContext(), aODFVersion, HasValidSignatures()));
1854 if (bSignScriptingContent)
1855 xSigner->showScriptingContentSignatures(GetMedium()->GetZipStorageToSign_Impl(),
1856 uno::Reference<io::XInputStream>());
1857 else
1858 {
1859 uno::Reference<embed::XStorage> xStorage = GetMedium()->GetZipStorageToSign_Impl();
1860 if (xStorage.is())
1861 xSigner->showDocumentContentSignatures(xStorage,
1862 uno::Reference<io::XInputStream>());
1863 else
1864 {
1865 std::unique_ptr<SvStream> pStream(
1866 utl::UcbStreamHelper::CreateStream(GetName(), StreamMode::READ));
1867 uno::Reference<io::XInputStream> xStream(new utl::OStreamWrapper(*pStream));
1868 xSigner->showDocumentContentSignatures(uno::Reference<embed::XStorage>(),
1869 xStream);
1870 }
1871 }
1872 }
1873 catch (const uno::Exception&)
1874 {
1875 SAL_WARN("sfx.doc", "Couldn't use signing functionality!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "sfx.doc")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "Couldn't use signing functionality!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"
), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1875" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't use signing functionality!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Couldn't use signing functionality!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1875" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Couldn't use signing functionality!") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), (
"/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1875" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "Couldn't use signing functionality!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "Couldn't use signing functionality!"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sfx.doc"), ("/home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx"
":" "1875" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
1876 }
1877 return true;
1878 }
1879 return false;
1880}
1881
1882bool SfxObjectShell::HasValidSignatures() const
1883{
1884 return pImpl->nDocumentSignatureState == SignatureState::OK
1885 || pImpl->nDocumentSignatureState == SignatureState::NOTVALIDATED
1886 || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK;
1887}
1888
1889SignatureState SfxObjectShell::GetDocumentSignatureState()
1890{
1891 return ImplGetSignatureState();
1892}
1893
1894void SfxObjectShell::SignDocumentContent(weld::Window* pDialogParent)
1895{
1896 if (!PrepareForSigning(pDialogParent))
1897 return;
1898
1899 if (CheckIsReadonly(false))
1900 return;
1901
1902 bool bSignSuccess = GetMedium()->SignContents_Impl(pDialogParent, false, HasValidSignatures());
1903
1904 AfterSigning(bSignSuccess, false);
1905}
1906
1907bool SfxObjectShell::SignDocumentContentUsingCertificate(const Reference<XCertificate>& xCertificate)
1908{
1909 // 1. PrepareForSigning
1910
1911 // check whether the document is signed
1912 ImplGetSignatureState(false); // document signature
1913 if (GetMedium() && GetMedium()->GetFilter() && GetMedium()->GetFilter()->IsOwnFormat())
1914 ImplGetSignatureState( true ); // script signature
1915 bool bHasSign = ( pImpl->nScriptingSignatureState != SignatureState::NOSIGNATURES || pImpl->nDocumentSignatureState != SignatureState::NOSIGNATURES );
1916
1917 // the target ODF version on saving (only valid when signing ODF of course)
1918 SvtSaveOptions aSaveOpt;
1919 SvtSaveOptions::ODFSaneDefaultVersion nVersion = aSaveOpt.GetODFSaneDefaultVersion();
1920
1921 // the document is not new and is not modified
1922 OUString aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(GetStorage()));
1923
1924 if (IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
1925 || (GetMedium()->GetFilter()->IsOwnFormat() && aODFVersion.compareTo(ODFVER_012_TEXT"1.2") < 0 && !bHasSign))
1926 {
1927 if (nVersion >= SvtSaveOptions::ODFSVER_012)
1928 {
1929 sal_uInt16 nId = SID_SAVEDOC(5000 + 505);
1930 if ( !GetMedium() || GetMedium()->GetName().isEmpty() )
1931 nId = SID_SAVEASDOC(5000 + 502);
1932 SfxRequest aSaveRequest( nId, SfxCallMode::SLOT, GetPool() );
1933 //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
1934 SetModified();
1935 ExecFile_Impl( aSaveRequest );
1936
1937 // Check if it is stored a format which supports signing
1938 if (GetMedium() && GetMedium()->GetFilter() && !GetMedium()->GetName().isEmpty()
1939 && ((!GetMedium()->GetFilter()->IsOwnFormat()
1940 && !GetMedium()->GetFilter()->GetSupportsSigning())
1941 || (GetMedium()->GetFilter()->IsOwnFormat()
1942 && !GetMedium()->HasStorage_Impl())))
1943 {
1944 return false;
1945 }
1946 }
1947 else
1948 {
1949 return false;
1950 }
1951
1952 if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
1953 return false;
1954 }
1955
1956 // the document is not modified currently, so it can not become modified after signing
1957 pImpl->m_bAllowModifiedBackAfterSigning = false;
1958 if ( IsEnableSetModified() )
1959 {
1960 EnableSetModified( false );
1961 pImpl->m_bAllowModifiedBackAfterSigning = true;
1962 }
1963
1964 // we have to store to the original document, the original medium should be closed for this time
1965 bool bResult = ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium);
1966
1967 if (!bResult)
1968 return false;
1969
1970 GetMedium()->CloseAndRelease();
1971
1972 // 2. Check Read-Only
1973 if (GetMedium()->IsOriginallyReadOnly())
1974 return false;
1975
1976 // 3. Sign
1977 bool bSignSuccess = GetMedium()->SignDocumentContentUsingCertificate(
1978 GetBaseModel(), HasValidSignatures(), xCertificate);
1979
1980 // 4. AfterSigning
1981 AfterSigning(bSignSuccess, false);
1982
1983 return true;
1984}
1985
1986void SfxObjectShell::SignSignatureLine(weld::Window* pDialogParent,
1987 const OUString& aSignatureLineId,
1988 const Reference<XCertificate>& xCert,
1989 const Reference<XGraphic>& xValidGraphic,
1990 const Reference<XGraphic>& xInvalidGraphic,
1991 const OUString& aComment)
1992{
1993 if (!PrepareForSigning(pDialogParent))
1994 return;
1995
1996 if (CheckIsReadonly(false))
1997 return;
1998
1999 bool bSignSuccess = GetMedium()->SignContents_Impl(pDialogParent,
2000 false, HasValidSignatures(), aSignatureLineId, xCert, xValidGraphic, xInvalidGraphic, aComment);
2001
2002 AfterSigning(bSignSuccess, false);
2003
2004 // Reload the document to get the updated graphic
2005 // FIXME: Update just the signature line graphic instead of reloading the document
2006 SfxViewFrame *pFrame = GetFrame();
2007 if (pFrame)
2008 pFrame->GetDispatcher()->Execute(SID_RELOAD(5000 + 508));
2009}
2010
2011SignatureState SfxObjectShell::GetScriptingSignatureState()
2012{
2013 return ImplGetSignatureState( true );
2014}
2015
2016void SfxObjectShell::SignScriptingContent(weld::Window* pDialogParent)
2017{
2018 if (!PrepareForSigning(pDialogParent))
2019 return;
2020
2021 if (CheckIsReadonly(true))
2022 return;
2023
2024 bool bSignSuccess = GetMedium()->SignContents_Impl(pDialogParent, true, HasValidSignatures());
2025
2026 AfterSigning(bSignSuccess, true);
2027}
2028
2029namespace
2030{
2031 class theSfxObjectShellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSfxObjectShellUnoTunnelId > {};
2032}
2033
2034const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId()
2035{
2036 return theSfxObjectShellUnoTunnelId::get().getSeq();
2037}
2038
2039/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/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#ifndef INCLUDED_TOOLS_REF_HXX
20#define INCLUDED_TOOLS_REF_HXX
21
22#include <sal/config.h>
23#include <cassert>
24#include <tools/toolsdllapi.h>
25#include <utility>
26
27/**
28 This implements similar functionality to boost::intrusive_ptr
29*/
30
31namespace tools {
32
33/** T must be a class that extends SvRefBase */
34template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final {
35public:
36 SvRef(): pObj(nullptr) {}
37
38 SvRef(SvRef&& rObj) noexcept
39 {
40 pObj = rObj.pObj;
41 rObj.pObj = nullptr;
42 }
43
44 SvRef(SvRef const & rObj): pObj(rObj.pObj)
45 {
46 if (pObj != nullptr) pObj->AddNextRef();
47 }
48
49 SvRef(T * pObjP): pObj(pObjP)
50 {
51 if (pObj != nullptr) pObj->AddFirstRef();
52 }
53
54 ~SvRef()
55 {
56 if (pObj != nullptr) pObj->ReleaseRef();
28
Taking true branch
29
Calling 'SvRefBase::ReleaseRef'
36
Returning; memory was released
57 }
58
59 void clear()
60 {
61 if (pObj != nullptr) {
62 T * pRefObj = pObj;
63 pObj = nullptr;
64 pRefObj->ReleaseRef();
65 }
66 }
67
68 SvRef & operator =(SvRef const & rObj)
69 {
70 if (rObj.pObj != nullptr) {
71 rObj.pObj->AddNextRef();
72 }
73 T * pRefObj = pObj;
74 pObj = rObj.pObj;
75 if (pRefObj != nullptr) {
76 pRefObj->ReleaseRef();
77 }
78 return *this;
79 }
80
81 SvRef & operator =(SvRef && rObj)
82 {
83 if (pObj != nullptr) {
84 pObj->ReleaseRef();
85 }
86 pObj = rObj.pObj;
87 rObj.pObj = nullptr;
88 return *this;
89 }
90
91 bool is() const { return pObj != nullptr; }
92
93 explicit operator bool() const { return is(); }
94
95 T * get() const { return pObj; }
96
97 T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 97, __extension__ __PRETTY_FUNCTION__))
; return pObj; }
98
99 T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 99, __extension__ __PRETTY_FUNCTION__))
; return *pObj; }
100
101 bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; }
102 bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); }
103
104private:
105 T * pObj;
106};
107
108/**
109 * This implements similar functionality to std::make_shared.
110 */
111template<typename T, typename... Args>
112SvRef<T> make_ref(Args&& ... args)
113{
114 return SvRef<T>(new T(std::forward<Args>(args)...));
115}
116
117}
118
119/** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
120class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase
121{
122 // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
123 // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
124 unsigned int nRefCount : 31;
125 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
126 unsigned int bNoDelete : 1;
127
128protected:
129 virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
130
131public:
132 SvRefBase() : nRefCount(0), bNoDelete(1) {}
133 SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {}
134
135 SvRefBase & operator=(const SvRefBase &) { return *this; }
136
137 void RestoreNoDelete()
138 { bNoDelete = 1; }
139
140 void AddNextRef()
141 {
142 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
142, __extension__ __PRETTY_FUNCTION__))
;
143 ++nRefCount;
144 }
145
146 void AddFirstRef()
147 {
148 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
148, __extension__ __PRETTY_FUNCTION__))
;
149 if( bNoDelete )
150 bNoDelete = 0;
151 ++nRefCount;
152 }
153
154 void ReleaseRef()
155 {
156 assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail
("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 156, __extension__ __PRETTY_FUNCTION__))
;
30
Assuming field 'nRefCount' is >= 1
31
'?' condition is true
157 if( --nRefCount == 0 && !bNoDelete)
32
Assuming the condition is true
33
Assuming field 'bNoDelete' is 0
34
Taking true branch
158 {
159 // I'm not sure about the original purpose of this line, but right now
160 // it serves the purpose that anything that attempts to do an AddRef()
161 // after an object is deleted will trip an assert.
162 nRefCount = 1 << 30;
163 delete this;
35
Memory is released
164 }
165 }
166
167 unsigned int GetRefCount() const
168 { return nRefCount; }
169};
170
171template<typename T>
172class SvCompatWeakBase;
173
174/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
175*/
176template<typename T>
177class SvCompatWeakHdl final : public SvRefBase
178{
179 friend class SvCompatWeakBase<T>;
180 T* _pObj;
181
182 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
183
184public:
185 void ResetWeakBase( ) { _pObj = nullptr; }
186 T* GetObj() { return _pObj; }
187};
188
189/** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
190 Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
191*/
192template<typename T>
193class SvCompatWeakBase
194{
195 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
196
197public:
198 /** Does not use initializer due to compiler warnings,
199 because the lifetime of the _xHdl object can exceed the lifetime of this class.
200 */
201 SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
202
203 ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
204
205 SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); }
206};
207
208/** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
209*/
210template<typename T>
211class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef
212{
213 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
214public:
215 SvCompatWeakRef( ) {}
216 SvCompatWeakRef( T* pObj )
217 { if( pObj ) _xHdl = pObj->GetHdl(); }
218#if defined(__COVERITY__)
219 ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {}
220#endif
221 SvCompatWeakRef& operator = ( T * pObj )
222 { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; }
223 bool is() const
224 { return _xHdl.is() && _xHdl->GetObj(); }
225 explicit operator bool() const { return is(); }
226 T* operator -> () const
227 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
228 operator T* () const
229 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
230};
231
232#endif
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */