File: | home/maarten/src/libreoffice/core/sfx2/source/doc/objserv.cxx |
Warning: | line 1201, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||
2 | /* | ||||
3 | * This file is part of the LibreOffice project. | ||||
4 | * | ||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
8 | * | ||||
9 | * This file incorporates work covered by the following license notice: | ||||
10 | * | ||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||
13 | * with this work for additional information regarding copyright | ||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||
16 | * except in compliance with the License. You may obtain a copy of | ||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||
18 | */ | ||||
19 | |||||
20 | #include <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 | |||||
111 | using namespace ::com::sun::star; | ||||
112 | using namespace ::com::sun::star::lang; | ||||
113 | using namespace ::com::sun::star::uno; | ||||
114 | using namespace ::com::sun::star::ui::dialogs; | ||||
115 | using namespace ::com::sun::star::awt; | ||||
116 | using namespace ::com::sun::star::container; | ||||
117 | using namespace ::com::sun::star::beans; | ||||
118 | using namespace ::com::sun::star::document; | ||||
119 | using namespace ::com::sun::star::security; | ||||
120 | using namespace ::com::sun::star::task; | ||||
121 | using namespace ::com::sun::star::graphic; | ||||
122 | |||||
123 | #define ShellClass_SfxObjectShell | ||||
124 | #include <sfxslots.hxx> | ||||
125 | |||||
126 | SFX_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 | |||||
128 | void SfxObjectShell::InitInterface_Impl() | ||||
129 | { | ||||
130 | } | ||||
131 | |||||
132 | namespace { | ||||
133 | |||||
134 | class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper< css::util::XCloseListener > | ||||
135 | { | ||||
136 | bool m_bGotOwnership; | ||||
137 | bool m_bPreventClose; | ||||
138 | |||||
139 | public: | ||||
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 | |||||
156 | SfxClosePreventer_Impl::SfxClosePreventer_Impl() | ||||
157 | : m_bGotOwnership( false ) | ||||
158 | , m_bPreventClose( true ) | ||||
159 | { | ||||
160 | } | ||||
161 | |||||
162 | void 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 | |||||
173 | void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) | ||||
174 | {} | ||||
175 | |||||
176 | void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) | ||||
177 | {} | ||||
178 | |||||
179 | namespace { | ||||
180 | |||||
181 | class SfxInstanceCloseGuard_Impl | ||||
182 | { | ||||
183 | rtl::Reference<SfxClosePreventer_Impl> m_xPreventer; | ||||
184 | uno::Reference< util::XCloseable > m_xCloseable; | ||||
185 | |||||
186 | public: | ||||
187 | SfxInstanceCloseGuard_Impl() {} | ||||
188 | |||||
189 | ~SfxInstanceCloseGuard_Impl(); | ||||
190 | |||||
191 | bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable ); | ||||
192 | }; | ||||
193 | |||||
194 | } | ||||
195 | |||||
196 | bool 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 | |||||
219 | SfxInstanceCloseGuard_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 | |||||
248 | void 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 | |||||
259 | void 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 | |||||
271 | bool 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 | |||||
323 | void 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 | |||||
342 | void 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 | |||||
361 | void 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 | |||||
384 | uno::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 | |||||
400 | bool 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 | |||||
412 | uno::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 | |||||
442 | void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) | ||||
443 | { | ||||
444 | weld::Window* pDialogParent = rReq.GetFrameWeld(); | ||||
445 | if (!pDialogParent) | ||||
| |||||
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 ) | ||||
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) ) | ||||
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) | ||||
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 ) ) | ||||
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) ) | ||||
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
| ||||
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) ) | ||||
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
| ||||
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) ) | ||||
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
| ||||
914 | |||||
915 | uno::Sequence< beans::PropertyValue > aDispatchArgs; | ||||
916 | if ( rReq.GetArgs() ) | ||||
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
| ||||
923 | if ( !pSlot ) | ||||
924 | throw uno::Exception("no slot", nullptr); | ||||
925 | |||||
926 | SfxStoringHelper aHelper; | ||||
927 | |||||
928 | if ( QueryHiddenInformation( bIsPDFExport
| ||||
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 ) | ||||
975 | lErr = nErrorCode; | ||||
976 | |||||
977 | if ( lErr && nErrorCode == ERRCODE_NONEErrCode(0) ) | ||||
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 ) ) | ||||
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) ) | ||||
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) ) | ||||
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; | ||||
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() ) | ||||
1201 | GetMedium()->SetUpdatePickList( false ); | ||||
| |||||
1202 | |||||
1203 | // Ignore()-branches have already returned | ||||
1204 | rReq.Done(); | ||||
1205 | } | ||||
1206 | |||||
1207 | |||||
1208 | void 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 | |||||
1476 | IMPL_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 | |||||
1481 | void 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 | |||||
1516 | void 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 | |||||
1592 | void 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 | |||||
1609 | void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/) | ||||
1610 | { | ||||
1611 | } | ||||
1612 | |||||
1613 | /// Does this ZIP storage have a signature stream? | ||||
1614 | static 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 | |||||
1643 | uno::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 | |||||
1705 | SignatureState 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 | |||||
1727 | bool 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 | |||||
1817 | void 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 | |||||
1829 | void 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 | |||||
1842 | bool 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 | |||||
1882 | bool SfxObjectShell::HasValidSignatures() const | ||||
1883 | { | ||||
1884 | return pImpl->nDocumentSignatureState == SignatureState::OK | ||||
1885 | || pImpl->nDocumentSignatureState == SignatureState::NOTVALIDATED | ||||
1886 | || pImpl->nDocumentSignatureState == SignatureState::PARTIAL_OK; | ||||
1887 | } | ||||
1888 | |||||
1889 | SignatureState SfxObjectShell::GetDocumentSignatureState() | ||||
1890 | { | ||||
1891 | return ImplGetSignatureState(); | ||||
1892 | } | ||||
1893 | |||||
1894 | void 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 | |||||
1907 | bool 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 | |||||
1986 | void 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 | |||||
2011 | SignatureState SfxObjectShell::GetScriptingSignatureState() | ||||
2012 | { | ||||
2013 | return ImplGetSignatureState( true ); | ||||
2014 | } | ||||
2015 | |||||
2016 | void 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 | |||||
2029 | namespace | ||||
2030 | { | ||||
2031 | class theSfxObjectShellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSfxObjectShellUnoTunnelId > {}; | ||||
2032 | } | ||||
2033 | |||||
2034 | const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId() | ||||
2035 | { | ||||
2036 | return theSfxObjectShellUnoTunnelId::get().getSeq(); | ||||
2037 | } | ||||
2038 | |||||
2039 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_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 | |
31 | namespace tools { |
32 | |
33 | /** T must be a class that extends SvRefBase */ |
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { |
35 | public: |
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(); |
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 | |
104 | private: |
105 | T * pObj; |
106 | }; |
107 | |
108 | /** |
109 | * This implements similar functionality to std::make_shared. |
110 | */ |
111 | template<typename T, typename... Args> |
112 | SvRef<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 */ |
120 | class 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 | |
128 | protected: |
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; |
130 | |
131 | public: |
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__)); |
157 | if( --nRefCount == 0 && !bNoDelete) |
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; |
164 | } |
165 | } |
166 | |
167 | unsigned int GetRefCount() const |
168 | { return nRefCount; } |
169 | }; |
170 | |
171 | template<typename T> |
172 | class SvCompatWeakBase; |
173 | |
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. |
175 | */ |
176 | template<typename T> |
177 | class SvCompatWeakHdl final : public SvRefBase |
178 | { |
179 | friend class SvCompatWeakBase<T>; |
180 | T* _pObj; |
181 | |
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} |
183 | |
184 | public: |
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 | */ |
192 | template<typename T> |
193 | class SvCompatWeakBase |
194 | { |
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
196 | |
197 | public: |
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 | */ |
210 | template<typename T> |
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef |
212 | { |
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
214 | public: |
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: */ |