Line data Source code
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 <sot/storage.hxx>
23 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
24 : #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
25 : #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
26 : #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
27 : #include <com/sun/star/ui/dialogs/XControlAccess.hpp>
28 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 : #include <com/sun/star/beans/XPropertyAccess.hpp>
30 : #include <com/sun/star/beans/XPropertySet.hpp>
31 : #include <com/sun/star/beans/PropertyValue.hpp>
32 : #include <com/sun/star/container/XNameAccess.hpp>
33 : #include <com/sun/star/document/XCmisDocument.hpp>
34 : #include <com/sun/star/document/XExporter.hpp>
35 : #include <com/sun/star/task/ErrorCodeIOException.hpp>
36 : #include <com/sun/star/task/InteractionHandler.hpp>
37 : #include <com/sun/star/task/XStatusIndicator.hpp>
38 : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
39 : #include <com/sun/star/frame/DocumentTemplates.hpp>
40 : #include <com/sun/star/frame/XController2.hpp>
41 : #include <com/sun/star/frame/XDocumentTemplates.hpp>
42 : #include <com/sun/star/frame/XStorable.hpp>
43 : #include <comphelper/processfactory.hxx>
44 : #include <comphelper/servicehelper.hxx>
45 : #include <com/sun/star/security/CertificateValidity.hpp>
46 :
47 : #include <com/sun/star/security/DocumentSignatureInformation.hpp>
48 : #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
49 : #include <tools/urlobj.hxx>
50 : #include <svl/whiter.hxx>
51 : #include <vcl/layout.hxx>
52 : #include <svl/intitem.hxx>
53 : #include <svl/eitem.hxx>
54 : #include <svl/visitem.hxx>
55 : #include <vcl/wrkwin.hxx>
56 : #include <svtools/sfxecode.hxx>
57 : #include <svtools/ehdl.hxx>
58 :
59 : #include <comphelper/string.hxx>
60 : #include <basic/sbx.hxx>
61 : #include <unotools/pathoptions.hxx>
62 : #include <unotools/useroptions.hxx>
63 : #include <unotools/saveopt.hxx>
64 : #include <svtools/asynclink.hxx>
65 : #include <svtools/miscopt.hxx>
66 : #include <comphelper/documentconstants.hxx>
67 :
68 : #include <sfx2/app.hxx>
69 : #include <sfx2/signaturestate.hxx>
70 : #include <sfx2/sfxresid.hxx>
71 : #include <sfx2/event.hxx>
72 : #include <sfx2/request.hxx>
73 : #include <sfx2/printer.hxx>
74 : #include <sfx2/viewsh.hxx>
75 : #include <sfx2/docfilt.hxx>
76 : #include <sfx2/docfile.hxx>
77 : #include <sfx2/dispatch.hxx>
78 : #include <sfx2/dinfdlg.hxx>
79 : #include <sfx2/objitem.hxx>
80 : #include <sfx2/objsh.hxx>
81 : #include "objshimp.hxx"
82 : #include "sfxtypes.hxx"
83 : #include <sfx2/module.hxx>
84 : #include <sfx2/viewfrm.hxx>
85 : #include "versdlg.hxx"
86 : #include "doc.hrc"
87 : #include <sfx2/docfac.hxx>
88 : #include <sfx2/fcontnr.hxx>
89 : #include <sfx2/sfxhelp.hxx>
90 : #include <sfx2/msgpool.hxx>
91 : #include <sfx2/objface.hxx>
92 : #include <sfx2/checkin.hxx>
93 :
94 : #include "../appl/app.hrc"
95 : #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
96 : #include <com/sun/star/embed/XTransactedObject.hpp>
97 : #include <com/sun/star/util/XCloneable.hpp>
98 : #include <com/sun/star/document/XDocumentProperties.hpp>
99 :
100 : #include "helpid.hrc"
101 :
102 : #include "guisaveas.hxx"
103 : #include <sfx2/templatedlg.hxx>
104 : #include <boost/scoped_ptr.hpp>
105 :
106 : using namespace ::com::sun::star;
107 : using namespace ::com::sun::star::lang;
108 : using namespace ::com::sun::star::uno;
109 : using namespace ::com::sun::star::ui::dialogs;
110 : using namespace ::com::sun::star::awt;
111 : using namespace ::com::sun::star::container;
112 : using namespace ::com::sun::star::beans;
113 : using namespace ::com::sun::star::document;
114 : using namespace ::com::sun::star::task;
115 :
116 : #define SfxObjectShell
117 : #include "sfxslots.hxx"
118 :
119 954 : SFX_IMPL_INTERFACE(SfxObjectShell, SfxShell, SfxResId(0))
120 :
121 303 : void SfxObjectShell::InitInterface_Impl()
122 : {
123 303 : }
124 :
125 0 : class SfxClosePreventer_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
126 : {
127 : bool m_bGotOwnership;
128 : bool m_bPreventClose;
129 :
130 : public:
131 : SfxClosePreventer_Impl();
132 :
133 0 : bool HasOwnership() { return m_bGotOwnership; }
134 :
135 0 : void SetPreventClose( bool bPrevent ) { m_bPreventClose = bPrevent; }
136 :
137 : virtual void SAL_CALL queryClosing( const lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
138 : throw ( uno::RuntimeException, util::CloseVetoException, std::exception ) SAL_OVERRIDE;
139 :
140 : virtual void SAL_CALL notifyClosing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
141 :
142 : virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
143 :
144 : } ;
145 :
146 0 : SfxClosePreventer_Impl::SfxClosePreventer_Impl()
147 : : m_bGotOwnership( false )
148 0 : , m_bPreventClose( true )
149 : {
150 0 : }
151 :
152 0 : void SAL_CALL SfxClosePreventer_Impl::queryClosing( const lang::EventObject&, sal_Bool bDeliverOwnership )
153 : throw ( uno::RuntimeException, util::CloseVetoException, std::exception )
154 : {
155 0 : if ( m_bPreventClose )
156 : {
157 0 : if ( !m_bGotOwnership )
158 0 : m_bGotOwnership = bDeliverOwnership;
159 :
160 0 : throw util::CloseVetoException();
161 : }
162 0 : }
163 :
164 0 : void SAL_CALL SfxClosePreventer_Impl::notifyClosing( const lang::EventObject& ) throw ( uno::RuntimeException, std::exception )
165 0 : {}
166 :
167 0 : void SAL_CALL SfxClosePreventer_Impl::disposing( const lang::EventObject& ) throw ( uno::RuntimeException, std::exception )
168 0 : {}
169 :
170 :
171 : class SfxInstanceCloseGuard_Impl
172 : {
173 : SfxClosePreventer_Impl* m_pPreventer;
174 : uno::Reference< util::XCloseListener > m_xPreventer;
175 : uno::Reference< util::XCloseable > m_xCloseable;
176 :
177 : public:
178 0 : SfxInstanceCloseGuard_Impl()
179 0 : : m_pPreventer( NULL )
180 0 : {}
181 :
182 : ~SfxInstanceCloseGuard_Impl();
183 :
184 : bool Init_Impl( const uno::Reference< util::XCloseable >& xCloseable );
185 : };
186 :
187 0 : bool SfxInstanceCloseGuard_Impl::Init_Impl( const uno::Reference< util::XCloseable >& xCloseable )
188 : {
189 0 : bool bResult = false;
190 :
191 : // do not allow reinit after the successful init
192 0 : if ( xCloseable.is() && !m_xCloseable.is() )
193 : {
194 : try
195 : {
196 0 : m_pPreventer = new SfxClosePreventer_Impl();
197 0 : m_xPreventer = uno::Reference< util::XCloseListener >( m_pPreventer );
198 0 : xCloseable->addCloseListener( m_xPreventer );
199 0 : m_xCloseable = xCloseable;
200 0 : bResult = true;
201 : }
202 0 : catch( uno::Exception& )
203 : {
204 : OSL_FAIL( "Could not register close listener!\n" );
205 : }
206 : }
207 :
208 0 : return bResult;
209 : }
210 :
211 0 : SfxInstanceCloseGuard_Impl::~SfxInstanceCloseGuard_Impl()
212 : {
213 0 : if ( m_xCloseable.is() && m_xPreventer.is() )
214 : {
215 : try
216 : {
217 0 : m_xCloseable->removeCloseListener( m_xPreventer );
218 : }
219 0 : catch( uno::Exception& )
220 : {
221 : }
222 :
223 : try
224 : {
225 0 : if ( m_pPreventer )
226 : {
227 0 : m_pPreventer->SetPreventClose( false );
228 :
229 0 : if ( m_pPreventer->HasOwnership() )
230 0 : m_xCloseable->close( sal_True ); // TODO: do it asynchronously
231 : }
232 : }
233 0 : catch( uno::Exception& )
234 : {
235 : }
236 : }
237 0 : }
238 :
239 :
240 :
241 0 : void SfxObjectShell::PrintExec_Impl(SfxRequest &rReq)
242 : {
243 0 : SfxViewFrame *pFrame = SfxViewFrame::GetFirst(this);
244 0 : if ( pFrame )
245 : {
246 0 : rReq.SetSlot( SID_PRINTDOC );
247 0 : pFrame->GetViewShell()->ExecuteSlot(rReq);
248 : }
249 0 : }
250 :
251 :
252 :
253 0 : void SfxObjectShell::PrintState_Impl(SfxItemSet &rSet)
254 : {
255 0 : bool bPrinting = false;
256 0 : SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
257 0 : if ( pFrame )
258 : {
259 0 : SfxPrinter *pPrinter = pFrame->GetViewShell()->GetPrinter();
260 0 : bPrinting = pPrinter && pPrinter->IsPrinting();
261 : }
262 0 : rSet.Put( SfxBoolItem( SID_PRINTOUT, bPrinting ) );
263 0 : }
264 :
265 :
266 :
267 1114 : bool SfxObjectShell::APISaveAs_Impl
268 : (
269 : const OUString& aFileName,
270 : SfxItemSet* aParams
271 : )
272 : {
273 1114 : bool bOk = false;
274 :
275 :
276 1114 : if ( GetMedium() )
277 : {
278 1114 : OUString aFilterName;
279 1114 : SFX_ITEMSET_ARG( aParams, pFilterNameItem, SfxStringItem, SID_FILTER_NAME, false );
280 1114 : if( pFilterNameItem )
281 : {
282 1100 : aFilterName = pFilterNameItem->GetValue();
283 : }
284 : else
285 : {
286 14 : SFX_ITEMSET_ARG( aParams, pContentTypeItem, SfxStringItem, SID_CONTENTTYPE, false );
287 14 : if ( pContentTypeItem )
288 : {
289 0 : const SfxFilter* pFilter = SfxFilterMatcher( OUString::createFromAscii(GetFactory().GetShortName()) ).GetFilter4Mime( pContentTypeItem->GetValue(), SFX_FILTER_EXPORT );
290 0 : if ( pFilter )
291 0 : aFilterName = pFilter->GetName();
292 : }
293 : }
294 :
295 : // in case no filter defined use default one
296 1114 : if( aFilterName.isEmpty() )
297 : {
298 14 : const SfxFilter* pFilt = SfxFilter::GetDefaultFilterFromFactory(GetFactory().GetFactoryName());
299 :
300 : DBG_ASSERT( pFilt, "No default filter!\n" );
301 14 : if( pFilt )
302 14 : aFilterName = pFilt->GetFilterName();
303 :
304 14 : aParams->Put(SfxStringItem( SID_FILTER_NAME, aFilterName));
305 : }
306 :
307 :
308 : {
309 1114 : SfxObjectShellRef xLock( this ); // ???
310 :
311 : // use the title that is provided in the media descriptor
312 1114 : SFX_ITEMSET_ARG( aParams, pDocTitleItem, SfxStringItem, SID_DOCINFO_TITLE, false );
313 1114 : if ( pDocTitleItem )
314 0 : getDocProperties()->setTitle( pDocTitleItem->GetValue() );
315 :
316 : bOk = CommonSaveAs_Impl( INetURLObject(aFileName), aFilterName,
317 1114 : aParams );
318 :
319 1114 : }
320 : }
321 :
322 1114 : return bOk;
323 : }
324 :
325 0 : void SfxObjectShell::CheckOut( )
326 : {
327 : try
328 : {
329 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
330 0 : xCmisDoc->checkOut( );
331 :
332 : // Remove the info bar
333 0 : SfxViewFrame* pViewFrame = GetFrame();
334 0 : pViewFrame->RemoveInfoBar( "checkout" );
335 : }
336 0 : catch ( const uno::RuntimeException& e )
337 : {
338 0 : boost::scoped_ptr<MessageDialog> pErrorBox(new MessageDialog( &GetFrame()->GetWindow(), e.Message ));
339 0 : pErrorBox->Execute( );
340 : }
341 0 : }
342 :
343 0 : void SfxObjectShell::CancelCheckOut( )
344 : {
345 : try
346 : {
347 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
348 0 : xCmisDoc->cancelCheckOut( );
349 :
350 0 : uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
351 0 : if ( xModifiable.is( ) )
352 0 : xModifiable->setModified( sal_False );
353 : }
354 0 : catch ( const uno::RuntimeException& e )
355 : {
356 0 : boost::scoped_ptr<MessageDialog> pErrorBox(new MessageDialog(&GetFrame()->GetWindow(), e.Message));
357 0 : pErrorBox->Execute( );
358 : }
359 0 : }
360 :
361 0 : void SfxObjectShell::CheckIn( )
362 : {
363 : try
364 : {
365 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
366 : // Pop up dialog to ask for comment and major
367 0 : SfxCheckinDialog checkinDlg( &GetFrame( )->GetWindow( ) );
368 0 : if ( checkinDlg.Execute( ) == RET_OK )
369 : {
370 0 : OUString sComment = checkinDlg.GetComment( );
371 0 : bool bMajor = checkinDlg.IsMajor( );
372 0 : xCmisDoc->checkIn( bMajor, sComment );
373 0 : uno::Reference< util::XModifiable > xModifiable( GetModel( ), uno::UNO_QUERY );
374 0 : if ( xModifiable.is( ) )
375 0 : xModifiable->setModified( sal_False );
376 0 : }
377 : }
378 0 : catch ( const uno::RuntimeException& e )
379 : {
380 0 : boost::scoped_ptr<MessageDialog> pErrorBox(new MessageDialog(&GetFrame()->GetWindow(), e.Message));
381 0 : pErrorBox->Execute( );
382 : }
383 0 : }
384 :
385 0 : uno::Sequence< document::CmisVersion > SfxObjectShell::GetCmisVersions( )
386 : {
387 : try
388 : {
389 0 : uno::Reference< document::XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY_THROW );
390 0 : return xCmisDoc->getAllVersions( );
391 : }
392 0 : catch ( const uno::RuntimeException& e )
393 : {
394 0 : boost::scoped_ptr<MessageDialog> pErrorBox(new MessageDialog(&GetFrame()->GetWindow(), e.Message));
395 0 : pErrorBox->Execute( );
396 : }
397 0 : return uno::Sequence< document::CmisVersion > ( );
398 : }
399 :
400 :
401 0 : void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq)
402 : {
403 :
404 0 : sal_uInt16 nId = rReq.GetSlot();
405 :
406 0 : if( SID_SIGNATURE == nId || SID_MACRO_SIGNATURE == nId )
407 : {
408 0 : if ( QueryHiddenInformation( WhenSigning, NULL ) == RET_YES )
409 0 : ( SID_SIGNATURE == nId ) ? SignDocumentContent() : SignScriptingContent();
410 0 : return;
411 : }
412 :
413 0 : if ( !GetMedium() && nId != SID_CLOSEDOC )
414 : {
415 0 : rReq.Ignore();
416 0 : return;
417 : }
418 :
419 : // this guard is created here to have it destruction at the end of the method
420 0 : SfxInstanceCloseGuard_Impl aModelGuard;
421 :
422 0 : bool bIsPDFExport = false;
423 0 : switch(nId)
424 : {
425 : case SID_VERSION:
426 : {
427 0 : SfxViewFrame* pFrame = GetFrame();
428 0 : if ( !pFrame )
429 0 : pFrame = SfxViewFrame::GetFirst( this );
430 0 : if ( !pFrame )
431 0 : return;
432 :
433 0 : if ( pFrame->GetFrame().GetParentFrame() )
434 : {
435 0 : pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
436 0 : return;
437 : }
438 :
439 0 : if ( !IsOwnStorageFormat_Impl( *GetMedium() ) )
440 0 : return;
441 :
442 0 : boost::scoped_ptr<SfxVersionDialog> pDlg(new SfxVersionDialog( pFrame, IsSaveVersionOnClose() ));
443 0 : pDlg->Execute();
444 0 : SetSaveVersionOnClose( pDlg->IsSaveVersionOnClose() );
445 0 : rReq.Done();
446 0 : return;
447 : }
448 :
449 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
450 : case SID_DOCINFO:
451 : {
452 0 : SFX_REQUEST_ARG(rReq, pDocInfItem, SfxDocumentInfoItem, SID_DOCINFO, false);
453 0 : if ( pDocInfItem )
454 : {
455 : // parameter, e.g. from replayed macro
456 0 : pDocInfItem->UpdateDocumentInfo(getDocProperties(), true);
457 0 : SetUseUserData( pDocInfItem->IsUseUserData() );
458 : }
459 : else
460 : {
461 : // no argument containing DocInfo; check optional arguments
462 0 : bool bReadOnly = IsReadOnly();
463 0 : SFX_REQUEST_ARG(rReq, pROItem, SfxBoolItem, SID_DOC_READONLY, false);
464 0 : if ( pROItem )
465 : // override readonly attribute of document
466 : // e.g. if a readonly document is saved elsewhere and user asks for editing DocInfo before
467 0 : bReadOnly = pROItem->GetValue();
468 :
469 : // collect data for dialog
470 0 : OUString aURL, aTitle;
471 0 : if ( HasName() )
472 : {
473 0 : aURL = GetMedium()->GetName();
474 0 : aTitle = GetTitle();
475 : }
476 : else
477 : {
478 0 : aURL = "private:factory/" + OUString::createFromAscii( GetFactory().GetShortName() );
479 :
480 0 : aTitle = GetTitle();
481 : }
482 :
483 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
484 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
485 :
486 : SfxDocumentInfoItem aDocInfoItem( aURL, getDocProperties(), aCmisProperties,
487 0 : IsUseUserData() );
488 0 : if ( !GetSlotState( SID_DOCTEMPLATE ) )
489 : // templates not supported
490 0 : aDocInfoItem.SetTemplate(false);
491 :
492 0 : SfxItemSet aSet(GetPool(), SID_DOCINFO, SID_DOCINFO, SID_DOC_READONLY, SID_DOC_READONLY,
493 : SID_EXPLORER_PROPS_START, SID_EXPLORER_PROPS_START, SID_BASEURL, SID_BASEURL,
494 0 : 0L );
495 0 : aSet.Put( aDocInfoItem );
496 0 : aSet.Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
497 0 : aSet.Put( SfxStringItem( SID_EXPLORER_PROPS_START, aTitle ) );
498 0 : aSet.Put( SfxStringItem( SID_BASEURL, GetMedium()->GetBaseURL() ) );
499 :
500 : // creating dialog is done via virtual method; application will
501 : // add its own statistics page
502 0 : boost::scoped_ptr<SfxDocumentInfoDialog> pDlg(CreateDocumentInfoDialog(0, aSet));
503 0 : if ( RET_OK == pDlg->Execute() )
504 : {
505 0 : SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pDocInfoItem, SfxDocumentInfoItem, SID_DOCINFO, false);
506 0 : if ( pDocInfoItem )
507 : {
508 : // user has done some changes to DocumentInfo
509 0 : pDocInfoItem->UpdateDocumentInfo(getDocProperties());
510 : uno::Sequence< document::CmisProperty > aNewCmisProperties =
511 0 : pDocInfoItem->GetCmisProperties( );
512 0 : if ( aNewCmisProperties.getLength( ) > 0 )
513 0 : xCmisDoc->updateCmisProperties( aNewCmisProperties );
514 0 : SetUseUserData( ((const SfxDocumentInfoItem *)pDocInfoItem)->IsUseUserData() );
515 : // add data from dialog for possible recording purpose
516 : rReq.AppendItem( SfxDocumentInfoItem( GetTitle(),
517 0 : getDocProperties(), aNewCmisProperties, IsUseUserData() ) );
518 : }
519 :
520 0 : rReq.Done();
521 : }
522 : else
523 : // nothing done; no recording
524 0 : rReq.Ignore();
525 : }
526 :
527 0 : return;
528 : }
529 :
530 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
531 :
532 : case SID_EXPORTDOCASPDF:
533 : case SID_DIRECTEXPORTDOCASPDF:
534 0 : bIsPDFExport = true;
535 : //fall-through
536 : case SID_EXPORTDOC:
537 : case SID_SAVEASDOC:
538 : case SID_SAVEDOC:
539 : {
540 : // derived class may decide to abort this
541 0 : if( !QuerySlotExecutable( nId ) )
542 : {
543 0 : rReq.SetReturnValue( SfxBoolItem( 0, false ) );
544 0 : return;
545 : }
546 :
547 : //!! detailed analysis of an error code
548 0 : SfxObjectShellRef xLock( this );
549 :
550 : // the model can not be closed till the end of this method
551 : // if somebody tries to close it during this time the model will be closed
552 : // at the end of the method
553 0 : aModelGuard.Init_Impl( uno::Reference< util::XCloseable >( GetModel(), uno::UNO_QUERY ) );
554 :
555 0 : sal_uInt32 nErrorCode = ERRCODE_NONE;
556 :
557 : // by default versions should be preserved always except in case of an explicit
558 : // SaveAs via GUI, so the flag must be set accordingly
559 0 : pImp->bPreserveVersions = (nId == SID_SAVEDOC);
560 : try
561 : {
562 0 : SfxErrorContext aEc( ERRCTX_SFX_SAVEASDOC, GetTitle() ); // ???
563 :
564 0 : if ( nId == SID_SAVEASDOC )
565 : {
566 : // in case of plugin mode the SaveAs operation means SaveTo
567 0 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pViewOnlyItem, SfxBoolItem, SID_VIEWONLY, false );
568 0 : if ( pViewOnlyItem && pViewOnlyItem->GetValue() )
569 0 : rReq.AppendItem( SfxBoolItem( SID_SAVETO, true ) );
570 : }
571 :
572 : // TODO/LATER: do the following GUI related actions in standalown method
573 :
574 : // Introduce a status indicator for GUI operation
575 0 : SFX_REQUEST_ARG( rReq, pStatusIndicatorItem, SfxUnoAnyItem, SID_PROGRESS_STATUSBAR_CONTROL, false );
576 0 : if ( !pStatusIndicatorItem )
577 : {
578 : // get statusindicator
579 0 : uno::Reference< task::XStatusIndicator > xStatusIndicator;
580 0 : uno::Reference < frame::XController > xCtrl( GetModel()->getCurrentController() );
581 0 : if ( xCtrl.is() )
582 : {
583 0 : uno::Reference< task::XStatusIndicatorFactory > xStatFactory( xCtrl->getFrame(), uno::UNO_QUERY );
584 0 : if( xStatFactory.is() )
585 0 : xStatusIndicator = xStatFactory->createStatusIndicator();
586 : }
587 :
588 : OSL_ENSURE( xStatusIndicator.is(), "Can not retrieve default status indicator!\n" );
589 :
590 0 : if ( xStatusIndicator.is() )
591 : {
592 0 : SfxUnoAnyItem aStatIndItem( SID_PROGRESS_STATUSBAR_CONTROL, uno::makeAny( xStatusIndicator ) );
593 :
594 0 : if ( nId == SID_SAVEDOC )
595 : {
596 : // in case of saving it is not possible to transport the parameters from here
597 : // but it is not clear here whether the saving will be done or saveAs operation
598 0 : GetMedium()->GetItemSet()->Put( aStatIndItem );
599 : }
600 :
601 0 : rReq.AppendItem( aStatIndItem );
602 0 : }
603 : }
604 0 : else if ( nId == SID_SAVEDOC )
605 : {
606 : // in case of saving it is not possible to transport the parameters from here
607 : // but it is not clear here whether the saving will be done or saveAs operation
608 0 : GetMedium()->GetItemSet()->Put( *pStatusIndicatorItem );
609 : }
610 :
611 : // Introduce an interaction handler for GUI operation
612 0 : SFX_REQUEST_ARG( rReq, pInteractionHandlerItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, false );
613 0 : if ( !pInteractionHandlerItem )
614 : {
615 0 : uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
616 : uno::Reference< task::XInteractionHandler2 > xInteract(
617 0 : task::InteractionHandler::createWithParent(xContext, 0) );
618 :
619 0 : SfxUnoAnyItem aInteractionItem( SID_INTERACTIONHANDLER, uno::makeAny( xInteract ) );
620 0 : if ( nId == SID_SAVEDOC )
621 : {
622 : // in case of saving it is not possible to transport the parameters from here
623 : // but it is not clear here whether the saving will be done or saveAs operation
624 0 : GetMedium()->GetItemSet()->Put( aInteractionItem );
625 : }
626 :
627 0 : rReq.AppendItem( aInteractionItem );
628 : }
629 0 : else if ( nId == SID_SAVEDOC )
630 : {
631 : // in case of saving it is not possible to transport the parameters from here
632 : // but it is not clear here whether the saving will be done or saveAs operation
633 0 : GetMedium()->GetItemSet()->Put( *pInteractionHandlerItem );
634 : }
635 :
636 :
637 0 : bool bPreselectPassword = false;
638 0 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
639 0 : SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pOldPasswordItem, SfxStringItem, SID_PASSWORD, false );
640 0 : if ( pOldEncryptionDataItem || pOldPasswordItem )
641 0 : bPreselectPassword = true;
642 :
643 0 : uno::Sequence< beans::PropertyValue > aDispatchArgs;
644 0 : if ( rReq.GetArgs() )
645 : TransformItems( nId,
646 0 : *rReq.GetArgs(),
647 : aDispatchArgs,
648 0 : NULL );
649 :
650 0 : const SfxSlot* pSlot = GetModule()->GetSlotPool()->GetSlot( nId );
651 0 : if ( !pSlot )
652 0 : throw uno::Exception();
653 :
654 0 : SfxStoringHelper aHelper;
655 :
656 0 : if ( QueryHiddenInformation( bIsPDFExport ? WhenCreatingPDF : WhenSaving, NULL ) == RET_YES )
657 : {
658 : aHelper.GUIStoreModel( GetModel(),
659 : OUString::createFromAscii( pSlot->GetUnoName() ),
660 : aDispatchArgs,
661 : bPreselectPassword,
662 : GetSharedFileURL(),
663 0 : GetDocumentSignatureState() );
664 : }
665 : else
666 : {
667 : // the user has decided not to store the document
668 : throw task::ErrorCodeIOException(
669 : "SfxObjectShell::ExecFile_Impl: ERRCODE_IO_ABORT",
670 0 : uno::Reference< uno::XInterface >(), ERRCODE_IO_ABORT);
671 : }
672 :
673 : // merge aDispatchArgs to the request
674 0 : SfxAllItemSet aResultParams( GetPool() );
675 : TransformParameters( nId,
676 : aDispatchArgs,
677 : aResultParams,
678 0 : NULL );
679 0 : rReq.SetArgs( aResultParams );
680 :
681 : // the StoreAsURL/StoreToURL method have called this method with false
682 : // so it has to be restored to true here since it is a call from GUI
683 0 : GetMedium()->SetUpdatePickList( true );
684 :
685 : // TODO: in future it must be done in followind way
686 : // if document is opened from GUI it is immediatelly appears in the picklist
687 : // if the document is a new one then it appears in the picklist immediatelly
688 : // after SaveAs operation triggered from GUI
689 : }
690 0 : catch( const task::ErrorCodeIOException& aErrorEx )
691 : {
692 0 : nErrorCode = (sal_uInt32)aErrorEx.ErrCode;
693 : }
694 0 : catch( Exception& )
695 : {
696 0 : nErrorCode = ERRCODE_IO_GENERAL;
697 : }
698 :
699 : // by default versions should be preserved always except in case of an explicit
700 : // SaveAs via GUI, so the flag must be reset to guarantee this
701 0 : pImp->bPreserveVersions = true;
702 0 : sal_uIntPtr lErr=GetErrorCode();
703 :
704 0 : if ( !lErr && nErrorCode )
705 0 : lErr = nErrorCode;
706 :
707 0 : if ( lErr && nErrorCode == ERRCODE_NONE )
708 : {
709 0 : SFX_REQUEST_ARG( rReq, pWarnItem, SfxBoolItem, SID_FAIL_ON_WARNING, false );
710 0 : if ( pWarnItem && pWarnItem->GetValue() )
711 0 : nErrorCode = lErr;
712 : }
713 :
714 : // may be nErrorCode should be shown in future
715 0 : if ( lErr != ERRCODE_IO_ABORT )
716 : {
717 0 : SfxErrorContext aEc(ERRCTX_SFX_SAVEASDOC,GetTitle());
718 0 : ErrorHandler::HandleError( lErr );
719 : }
720 :
721 0 : if ( nId == SID_EXPORTDOCASPDF )
722 : {
723 : // This function is used by the SendMail function that needs information if a export
724 : // file was written or not. This could be due to cancellation of the export
725 : // or due to an error. So IO abort must be handled like an error!
726 0 : nErrorCode = ( lErr != ERRCODE_IO_ABORT ) && ( nErrorCode == ERRCODE_NONE ) ? nErrorCode : lErr;
727 : }
728 :
729 0 : if ( nId == SID_SAVEASDOC && nErrorCode == ERRCODE_NONE )
730 : {
731 0 : SetReadOnlyUI(false);
732 : }
733 :
734 0 : rReq.SetReturnValue( SfxBoolItem(0, nErrorCode == ERRCODE_NONE ) );
735 :
736 0 : ResetError();
737 :
738 0 : Invalidate();
739 0 : break;
740 : }
741 :
742 : case SID_SAVEACOPY:
743 : {
744 0 : SfxAllItemSet aArgs( GetPool() );
745 0 : aArgs.Put( SfxBoolItem( SID_SAVEACOPYITEM, true ) );
746 0 : SfxRequest aSaveACopyReq( SID_EXPORTDOC, SfxCallMode::API, aArgs );
747 0 : ExecFile_Impl( aSaveACopyReq );
748 0 : if ( !aSaveACopyReq.IsDone() )
749 : {
750 0 : rReq.Ignore();
751 0 : return;
752 : }
753 0 : break;
754 : }
755 :
756 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
757 :
758 : case SID_CLOSEDOC:
759 : {
760 0 : SfxViewFrame *pFrame = GetFrame();
761 0 : if ( pFrame && pFrame->GetFrame().GetParentFrame() )
762 : {
763 : // If SID_CLOSEDOC is excecuted through menu and so on, but
764 : // the current document is in a frame, then the
765 : // FrameSetDocument should actually be closed.
766 0 : pFrame->GetTopViewFrame()->GetObjectShell()->ExecuteSlot( rReq );
767 0 : rReq.Done();
768 0 : return;
769 : }
770 :
771 0 : bool bInFrameSet = false;
772 0 : sal_uInt16 nFrames=0;
773 0 : pFrame = SfxViewFrame::GetFirst( this );
774 0 : while ( pFrame )
775 : {
776 0 : if ( pFrame->GetFrame().GetParentFrame() )
777 : {
778 : // In this document there still exists a view that is
779 : // in a FrameSet , which of course may not be closed
780 : // geclosed werden
781 0 : bInFrameSet = true;
782 : }
783 : else
784 0 : nFrames++;
785 :
786 0 : pFrame = SfxViewFrame::GetNext( *pFrame, this );
787 : }
788 :
789 0 : if ( bInFrameSet )
790 : {
791 : // Close all views that are not in a FrameSet.
792 0 : pFrame = SfxViewFrame::GetFirst( this );
793 0 : while ( pFrame )
794 : {
795 0 : if ( !pFrame->GetFrame().GetParentFrame() )
796 0 : pFrame->GetFrame().DoClose();
797 0 : pFrame = SfxViewFrame::GetNext( *pFrame, this );
798 : }
799 : }
800 :
801 : // Evaluate Parameter
802 0 : SFX_REQUEST_ARG(rReq, pSaveItem, SfxBoolItem, SID_CLOSEDOC_SAVE, false);
803 0 : SFX_REQUEST_ARG(rReq, pNameItem, SfxStringItem, SID_CLOSEDOC_FILENAME, false);
804 0 : if ( pSaveItem )
805 : {
806 0 : if ( pSaveItem->GetValue() )
807 : {
808 0 : if ( !pNameItem )
809 : {
810 : #if HAVE_FEATURE_SCRIPTING
811 0 : SbxBase::SetError( SbxERR_WRONG_ARGS );
812 : #endif
813 0 : rReq.Ignore();
814 0 : return;
815 : }
816 0 : SfxAllItemSet aArgs( GetPool() );
817 0 : SfxStringItem aTmpItem( SID_FILE_NAME, pNameItem->GetValue() );
818 0 : aArgs.Put( aTmpItem, aTmpItem.Which() );
819 0 : SfxRequest aSaveAsReq( SID_SAVEASDOC, SfxCallMode::API, aArgs );
820 0 : ExecFile_Impl( aSaveAsReq );
821 0 : if ( !aSaveAsReq.IsDone() )
822 : {
823 0 : rReq.Ignore();
824 0 : return;
825 0 : }
826 : }
827 : else
828 0 : SetModified(false);
829 : }
830 :
831 : // Cancelled by the user?
832 0 : if (!PrepareClose(true))
833 : {
834 0 : rReq.SetReturnValue( SfxBoolItem(0, false) );
835 0 : rReq.Done();
836 0 : return;
837 : }
838 :
839 0 : SetModified( false );
840 0 : sal_uIntPtr lErr = GetErrorCode();
841 0 : ErrorHandler::HandleError(lErr);
842 :
843 0 : rReq.SetReturnValue( SfxBoolItem(0, true) );
844 0 : rReq.Done();
845 0 : rReq.ReleaseArgs(); // because the pool is destroyed in Close
846 0 : DoClose();
847 0 : return;
848 : }
849 :
850 : // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
851 : case SID_DOCTEMPLATE:
852 : {
853 : // save as document templates
854 0 : SfxTemplateManagerDlg aDlg;
855 0 : aDlg.setDocumentModel(GetModel());
856 0 : aDlg.setSaveMode();
857 0 : aDlg.Execute();
858 :
859 0 : break;
860 : }
861 :
862 : case SID_CHECKOUT:
863 : {
864 0 : CheckOut( );
865 0 : break;
866 : }
867 : case SID_CANCELCHECKOUT:
868 : {
869 0 : if (MessageDialog(NULL, SfxResId(STR_QUERY_CANCELCHECKOUT), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO).Execute() == RET_YES)
870 : {
871 0 : CancelCheckOut( );
872 :
873 : // Reload the document as we may still have local changes
874 0 : SfxViewFrame *pFrame = GetFrame();
875 0 : if ( pFrame )
876 0 : pFrame->GetDispatcher()->Execute(SID_RELOAD);
877 : }
878 0 : break;
879 : }
880 : case SID_CHECKIN:
881 : {
882 0 : CheckIn( );
883 0 : break;
884 : }
885 : }
886 :
887 : // Prevent entry in the Pick-lists
888 0 : if ( rReq.IsAPI() )
889 0 : GetMedium()->SetUpdatePickList( false );
890 0 : else if ( rReq.GetArgs() )
891 : {
892 0 : SFX_ITEMSET_GET( *rReq.GetArgs(), pPicklistItem, SfxBoolItem, SID_PICKLIST, false );
893 0 : if ( pPicklistItem )
894 0 : GetMedium()->SetUpdatePickList( pPicklistItem->GetValue() );
895 : }
896 :
897 : // Ignore()-branches have already returned
898 0 : rReq.Done();
899 : }
900 :
901 :
902 :
903 6669 : void SfxObjectShell::GetState_Impl(SfxItemSet &rSet)
904 : {
905 6669 : SfxWhichIter aIter( rSet );
906 :
907 15181 : for ( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich() )
908 : {
909 8512 : switch ( nWhich )
910 : {
911 : case SID_DOCTEMPLATE :
912 : {
913 0 : if ( !GetFactory().GetTemplateFilter() )
914 0 : rSet.DisableItem( nWhich );
915 0 : break;
916 : }
917 :
918 : case SID_CHECKOUT:
919 : {
920 0 : bool bShow = false;
921 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
922 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties();
923 :
924 0 : if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
925 : {
926 : // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
927 0 : bool bIsGoogleFile = false;
928 0 : bool bCheckedOut = false;
929 0 : for ( sal_Int32 i = 0; i < aCmisProperties.getLength(); ++i )
930 : {
931 0 : if ( aCmisProperties[i].Id == "cmis:isVersionSeriesCheckedOut" )
932 : {
933 0 : uno::Sequence< sal_Bool > bTmp;
934 0 : aCmisProperties[i].Value >>= bTmp;
935 0 : bCheckedOut = bTmp[0];
936 : }
937 : // using title to know if it's a Google Drive file
938 : // maybe there's a safer way.
939 0 : if ( aCmisProperties[i].Name == "title" )
940 0 : bIsGoogleFile = true;
941 : }
942 0 : bShow = !bCheckedOut && !bIsGoogleFile;
943 : }
944 :
945 0 : if ( !bShow )
946 : {
947 0 : rSet.DisableItem( nWhich );
948 0 : rSet.Put( SfxVisibilityItem( nWhich, false ) );
949 0 : }
950 : }
951 0 : break;
952 :
953 : case SID_CANCELCHECKOUT:
954 : case SID_CHECKIN:
955 : {
956 0 : bool bShow = false;
957 0 : Reference< XCmisDocument > xCmisDoc( GetModel(), uno::UNO_QUERY );
958 0 : uno::Sequence< document::CmisProperty> aCmisProperties = xCmisDoc->getCmisProperties( );
959 :
960 0 : if ( xCmisDoc->isVersionable( ) && aCmisProperties.hasElements( ) )
961 : {
962 : // Loop over the CMIS Properties to find cmis:isVersionSeriesCheckedOut
963 0 : bool bFoundCheckedout = false;
964 0 : bool bCheckedOut = false;
965 0 : for ( sal_Int32 i = 0; i < aCmisProperties.getLength() && !bFoundCheckedout; ++i )
966 : {
967 0 : if ( aCmisProperties[i].Id == "cmis:isVersionSeriesCheckedOut" )
968 : {
969 0 : bFoundCheckedout = true;
970 0 : uno::Sequence< sal_Bool > bTmp;
971 0 : aCmisProperties[i].Value >>= bTmp;
972 0 : bCheckedOut = bTmp[0];
973 : }
974 : }
975 0 : bShow = bCheckedOut;
976 : }
977 :
978 0 : if ( !bShow )
979 : {
980 0 : rSet.DisableItem( nWhich );
981 0 : rSet.Put( SfxVisibilityItem( nWhich, false ) );
982 0 : }
983 : }
984 0 : break;
985 :
986 : case SID_VERSION:
987 : {
988 0 : SfxObjectShell *pDoc = this;
989 0 : SfxViewFrame* pFrame = GetFrame();
990 0 : if ( !pFrame )
991 0 : pFrame = SfxViewFrame::GetFirst( this );
992 0 : if ( pFrame )
993 : {
994 0 : if ( pFrame->GetFrame().GetParentFrame() )
995 : {
996 0 : pFrame = pFrame->GetTopViewFrame();
997 0 : pDoc = pFrame->GetObjectShell();
998 : }
999 : }
1000 :
1001 0 : if ( !pFrame || !pDoc->HasName() ||
1002 0 : !IsOwnStorageFormat_Impl( *pDoc->GetMedium() ) )
1003 0 : rSet.DisableItem( nWhich );
1004 0 : break;
1005 : }
1006 : case SID_SAVEDOC:
1007 : {
1008 1532 : SvtMiscOptions aMiscOptions;
1009 1532 : bool bAlwaysAllowSave = aMiscOptions.IsSaveAlwaysAllowed();
1010 1532 : bool bAllowSave = (bAlwaysAllowSave || IsModified());
1011 1532 : bool bMediumRO = IsReadOnlyMedium();
1012 1532 : if ( !bMediumRO && GetMedium() && bAllowSave )
1013 : rSet.Put(SfxStringItem(
1014 825 : nWhich, SfxResId(STR_SAVEDOC).toString()));
1015 : else
1016 707 : rSet.DisableItem(nWhich);
1017 : }
1018 1532 : break;
1019 :
1020 : case SID_DOCINFO:
1021 0 : if ( 0 != ( pImp->eFlags & SFXOBJECTSHELL_NODOCINFO ) )
1022 0 : rSet.DisableItem( nWhich );
1023 0 : break;
1024 :
1025 : case SID_CLOSEDOC:
1026 : {
1027 0 : SfxObjectShell *pDoc = this;
1028 0 : SfxViewFrame *pFrame = GetFrame();
1029 0 : if ( pFrame && pFrame->GetFrame().GetParentFrame() )
1030 : {
1031 :
1032 : // If SID_CLOSEDOC is excecuted through menu and so on, but
1033 : // the current document is in a frame, then the
1034 : // FrameSetDocument should actually be closed.
1035 0 : pDoc = pFrame->GetTopViewFrame()->GetObjectShell();
1036 : }
1037 :
1038 0 : if ( pDoc->GetFlags() & SFXOBJECTSHELL_DONTCLOSE )
1039 0 : rSet.DisableItem(nWhich);
1040 : else
1041 0 : rSet.Put(SfxStringItem(nWhich, SfxResId(STR_CLOSEDOC).toString()));
1042 0 : break;
1043 : }
1044 :
1045 : case SID_SAVEASDOC:
1046 : {
1047 1536 : if( ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) != SFX_LOADED_MAINDOCUMENT )
1048 : {
1049 0 : rSet.DisableItem( nWhich );
1050 0 : break;
1051 : }
1052 1536 : if ( /*!pCombinedFilters ||*/ !GetMedium() )
1053 0 : rSet.DisableItem( nWhich );
1054 : else
1055 1536 : rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEASDOC).toString() ) );
1056 1536 : break;
1057 : }
1058 :
1059 : case SID_SAVEACOPY:
1060 : {
1061 0 : if( ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) != SFX_LOADED_MAINDOCUMENT )
1062 : {
1063 0 : rSet.DisableItem( nWhich );
1064 0 : break;
1065 : }
1066 0 : if ( /*!pCombinedFilters ||*/ !GetMedium() )
1067 0 : rSet.DisableItem( nWhich );
1068 : else
1069 0 : rSet.Put( SfxStringItem( nWhich, SfxResId(STR_SAVEACOPY).toString() ) );
1070 0 : break;
1071 : }
1072 :
1073 : case SID_EXPORTDOCASPDF:
1074 : case SID_DIRECTEXPORTDOCASPDF:
1075 : {
1076 1562 : break;
1077 : }
1078 :
1079 : case SID_DOC_MODIFIED:
1080 : {
1081 1941 : rSet.Put( SfxBoolItem( SID_DOC_MODIFIED, IsModified() ) );
1082 1941 : break;
1083 : }
1084 :
1085 : case SID_MODIFIED:
1086 : {
1087 0 : rSet.Put( SfxBoolItem( SID_MODIFIED, IsModified() ) );
1088 0 : break;
1089 : }
1090 :
1091 : case SID_DOCINFO_TITLE:
1092 : {
1093 : rSet.Put( SfxStringItem(
1094 0 : SID_DOCINFO_TITLE, getDocProperties()->getTitle() ) );
1095 0 : break;
1096 : }
1097 : case SID_FILE_NAME:
1098 : {
1099 0 : if( GetMedium() && HasName() )
1100 : rSet.Put( SfxStringItem(
1101 0 : SID_FILE_NAME, GetMedium()->GetName() ) );
1102 0 : break;
1103 : }
1104 : case SID_SIGNATURE:
1105 : {
1106 1941 : rSet.Put( SfxUInt16Item( SID_SIGNATURE, GetDocumentSignatureState() ) );
1107 1941 : break;
1108 : }
1109 : case SID_MACRO_SIGNATURE:
1110 : {
1111 : // the slot makes sense only if there is a macro in the document
1112 0 : if ( pImp->documentStorageHasMacros() || pImp->aMacroMode.hasMacroLibrary() )
1113 0 : rSet.Put( SfxUInt16Item( SID_MACRO_SIGNATURE, GetScriptingSignatureState() ) );
1114 : else
1115 0 : rSet.DisableItem( nWhich );
1116 0 : break;
1117 : }
1118 : }
1119 6669 : }
1120 6669 : }
1121 :
1122 :
1123 :
1124 0 : void SfxObjectShell::ExecProps_Impl(SfxRequest &rReq)
1125 : {
1126 0 : switch ( rReq.GetSlot() )
1127 : {
1128 : case SID_MODIFIED:
1129 : {
1130 0 : SetModified( static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get(SID_MODIFIED)).GetValue() );
1131 0 : rReq.Done();
1132 0 : break;
1133 : }
1134 :
1135 : case SID_DOCTITLE:
1136 0 : SetTitle( static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_DOCTITLE)).GetValue() );
1137 0 : rReq.Done();
1138 0 : break;
1139 :
1140 : case SID_DOCINFO_AUTHOR :
1141 : {
1142 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1143 0 : getDocProperties()->setAuthor( aStr );
1144 0 : break;
1145 : }
1146 :
1147 : case SID_DOCINFO_COMMENTS :
1148 : {
1149 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1150 0 : getDocProperties()->setDescription( aStr );
1151 0 : break;
1152 : }
1153 :
1154 : case SID_DOCINFO_KEYWORDS :
1155 : {
1156 0 : OUString aStr = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(rReq.GetSlot())).GetValue();
1157 0 : getDocProperties()->setKeywords(
1158 0 : ::comphelper::string::convertCommaSeparated(aStr) );
1159 0 : break;
1160 : }
1161 : }
1162 0 : }
1163 :
1164 :
1165 :
1166 62 : void SfxObjectShell::StateProps_Impl(SfxItemSet &rSet)
1167 : {
1168 62 : SfxWhichIter aIter(rSet);
1169 124 : for ( sal_uInt16 nSID = aIter.FirstWhich(); nSID; nSID = aIter.NextWhich() )
1170 : {
1171 62 : switch ( nSID )
1172 : {
1173 : case SID_DOCINFO_AUTHOR :
1174 : {
1175 : rSet.Put( SfxStringItem( nSID,
1176 0 : getDocProperties()->getAuthor() ) );
1177 0 : break;
1178 : }
1179 :
1180 : case SID_DOCINFO_COMMENTS :
1181 : {
1182 : rSet.Put( SfxStringItem( nSID,
1183 0 : getDocProperties()->getDescription()) );
1184 0 : break;
1185 : }
1186 :
1187 : case SID_DOCINFO_KEYWORDS :
1188 : {
1189 : rSet.Put( SfxStringItem( nSID, ::comphelper::string::
1190 0 : convertCommaSeparated(getDocProperties()->getKeywords())) );
1191 0 : break;
1192 : }
1193 :
1194 : case SID_DOCPATH:
1195 : {
1196 : OSL_FAIL( "Not supported anymore!" );
1197 0 : break;
1198 : }
1199 :
1200 : case SID_DOCFULLNAME:
1201 : {
1202 62 : rSet.Put( SfxStringItem( SID_DOCFULLNAME, GetTitle(SFX_TITLE_FULLNAME) ) );
1203 62 : break;
1204 : }
1205 :
1206 : case SID_DOCTITLE:
1207 : {
1208 0 : rSet.Put( SfxStringItem( SID_DOCTITLE, GetTitle() ) );
1209 0 : break;
1210 : }
1211 :
1212 : case SID_DOC_READONLY:
1213 : {
1214 0 : rSet.Put( SfxBoolItem( SID_DOC_READONLY, IsReadOnly() ) );
1215 0 : break;
1216 : }
1217 :
1218 : case SID_DOC_SAVED:
1219 : {
1220 0 : rSet.Put( SfxBoolItem( SID_DOC_SAVED, !IsModified() ) );
1221 0 : break;
1222 : }
1223 :
1224 : case SID_CLOSING:
1225 : {
1226 0 : rSet.Put( SfxBoolItem( SID_CLOSING, false ) );
1227 0 : break;
1228 : }
1229 :
1230 : case SID_DOC_LOADING:
1231 : rSet.Put( SfxBoolItem( nSID, SFX_LOADED_MAINDOCUMENT !=
1232 0 : ( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) ) );
1233 0 : break;
1234 :
1235 : case SID_IMG_LOADING:
1236 : rSet.Put( SfxBoolItem( nSID, SFX_LOADED_IMAGES !=
1237 0 : ( pImp->nLoadedFlags & SFX_LOADED_IMAGES ) ) );
1238 0 : break;
1239 : }
1240 62 : }
1241 62 : }
1242 :
1243 :
1244 :
1245 0 : void SfxObjectShell::ExecView_Impl(SfxRequest &rReq)
1246 : {
1247 0 : switch ( rReq.GetSlot() )
1248 : {
1249 : case SID_ACTIVATE:
1250 : {
1251 0 : SfxViewFrame *pFrame = SfxViewFrame::GetFirst( this, true );
1252 0 : if ( pFrame )
1253 0 : pFrame->GetFrame().Appear();
1254 0 : rReq.SetReturnValue( SfxObjectItem( 0, pFrame ) );
1255 0 : rReq.Done();
1256 0 : break;
1257 : }
1258 : case SID_NEWWINDOWFOREDIT:
1259 : {
1260 0 : SfxViewFrame* pFrame = SfxViewFrame::Current();
1261 0 : if( pFrame->GetObjectShell() == this &&
1262 0 : ( pFrame->GetFrameType() & SFXFRAME_HASTITLE ) )
1263 0 : pFrame->ExecuteSlot( rReq );
1264 : else
1265 : {
1266 0 : OUString aFileName( GetObjectShell()->GetMedium()->GetName() );
1267 0 : if ( !aFileName.isEmpty() )
1268 : {
1269 0 : SfxStringItem aName( SID_FILE_NAME, aFileName );
1270 0 : SfxBoolItem aCreateView( SID_OPEN_NEW_VIEW, true );
1271 : SfxGetpApp()->GetAppDispatcher_Impl()->Execute(
1272 : SID_OPENDOC, SfxCallMode::ASYNCHRON, &aName,
1273 0 : &aCreateView, 0L);
1274 0 : }
1275 : }
1276 : }
1277 : }
1278 0 : }
1279 :
1280 :
1281 :
1282 0 : void SfxObjectShell::StateView_Impl(SfxItemSet& /*rSet*/)
1283 : {
1284 0 : }
1285 :
1286 6770 : sal_uInt16 SfxObjectShell::ImplCheckSignaturesInformation( const uno::Sequence< security::DocumentSignatureInformation >& aInfos )
1287 : {
1288 6770 : bool bCertValid = true;
1289 6770 : sal_uInt16 nResult = SIGNATURESTATE_NOSIGNATURES;
1290 6770 : int nInfos = aInfos.getLength();
1291 6770 : bool bCompleteSignature = true;
1292 6770 : if( nInfos )
1293 : {
1294 0 : nResult = SIGNATURESTATE_SIGNATURES_OK;
1295 0 : for ( int n = 0; n < nInfos; n++ )
1296 : {
1297 0 : if ( bCertValid )
1298 : {
1299 0 : sal_Int32 nCertStat = aInfos[n].CertificateStatus;
1300 0 : bCertValid = nCertStat == security::CertificateValidity::VALID ? sal_True : sal_False;
1301 : }
1302 :
1303 0 : if ( !aInfos[n].SignatureIsValid )
1304 : {
1305 0 : nResult = SIGNATURESTATE_SIGNATURES_BROKEN;
1306 0 : break; // we know enough
1307 : }
1308 0 : bCompleteSignature &= !aInfos[n].PartialDocumentSignature;
1309 : }
1310 : }
1311 :
1312 6770 : if ( nResult == SIGNATURESTATE_SIGNATURES_OK && !bCertValid )
1313 0 : nResult = SIGNATURESTATE_SIGNATURES_NOTVALIDATED;
1314 6770 : else if ( nResult == SIGNATURESTATE_SIGNATURES_OK && bCertValid && !bCompleteSignature)
1315 0 : nResult = SIGNATURESTATE_SIGNATURES_PARTIAL_OK;
1316 :
1317 : // this code must not check whether the document is modified
1318 : // it should only check the provided info
1319 :
1320 6770 : return nResult;
1321 : }
1322 :
1323 6770 : uno::Sequence< security::DocumentSignatureInformation > SfxObjectShell::ImplAnalyzeSignature( bool bScriptingContent, const uno::Reference< security::XDocumentDigitalSignatures >& xSigner )
1324 : {
1325 6770 : uno::Sequence< security::DocumentSignatureInformation > aResult;
1326 13540 : uno::Reference< security::XDocumentDigitalSignatures > xLocSigner = xSigner;
1327 :
1328 6770 : if ( GetMedium() && !GetMedium()->GetName().isEmpty() && IsOwnStorageFormat_Impl( *GetMedium()) && GetMedium()->GetStorage().is() )
1329 : {
1330 : try
1331 : {
1332 608 : if ( !xLocSigner.is() )
1333 : {
1334 608 : OUString aVersion;
1335 : try
1336 : {
1337 608 : uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1338 608 : xPropSet->getPropertyValue("Version") >>= aVersion;
1339 : }
1340 0 : catch( uno::Exception& )
1341 : {
1342 : }
1343 :
1344 608 : xLocSigner.set( security::DocumentDigitalSignatures::createWithVersion(comphelper::getProcessComponentContext(), aVersion) );
1345 :
1346 : }
1347 :
1348 214 : if ( bScriptingContent )
1349 0 : aResult = xLocSigner->verifyScriptingContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1350 0 : uno::Reference< io::XInputStream >() );
1351 : else
1352 642 : aResult = xLocSigner->verifyDocumentContentSignatures( GetMedium()->GetZipStorageToSign_Impl(),
1353 428 : uno::Reference< io::XInputStream >() );
1354 : }
1355 394 : catch( com::sun::star::uno::Exception& )
1356 : {
1357 : }
1358 : }
1359 :
1360 13540 : return aResult;
1361 : }
1362 :
1363 34398 : sal_uInt16 SfxObjectShell::ImplGetSignatureState( bool bScriptingContent )
1364 : {
1365 34398 : sal_Int16* pState = bScriptingContent ? &pImp->nScriptingSignatureState : &pImp->nDocumentSignatureState;
1366 :
1367 34398 : if ( *pState == SIGNATURESTATE_UNKNOWN )
1368 : {
1369 6770 : *pState = SIGNATURESTATE_NOSIGNATURES;
1370 :
1371 6770 : uno::Sequence< security::DocumentSignatureInformation > aInfos = ImplAnalyzeSignature( bScriptingContent );
1372 6770 : *pState = ImplCheckSignaturesInformation( aInfos );
1373 : }
1374 :
1375 34398 : if ( *pState == SIGNATURESTATE_SIGNATURES_OK || *pState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
1376 34398 : || *pState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK)
1377 : {
1378 0 : if ( IsModified() )
1379 0 : *pState = SIGNATURESTATE_SIGNATURES_INVALID;
1380 : }
1381 :
1382 34398 : return (sal_uInt16)*pState;
1383 : }
1384 :
1385 0 : void SfxObjectShell::ImplSign( bool bScriptingContent )
1386 : {
1387 : // Check if it is stored in OASIS format...
1388 0 : if ( GetMedium()
1389 0 : && GetMedium()->GetFilter()
1390 0 : && !GetMedium()->GetName().isEmpty()
1391 0 : && ( !GetMedium()->GetFilter()->IsOwnFormat()
1392 0 : || !GetMedium()->HasStorage_Impl()
1393 : )
1394 : )
1395 : {
1396 : // Only OASIS and OOo6.x formats will be handled further
1397 0 : MessageDialog( NULL, SfxResId( STR_INFO_WRONGDOCFORMAT ), VCL_MESSAGE_INFO ).Execute();
1398 0 : return;
1399 : }
1400 :
1401 : // check whether the document is signed
1402 0 : ImplGetSignatureState( false ); // document signature
1403 0 : ImplGetSignatureState( true ); // script signature
1404 0 : bool bHasSign = ( pImp->nScriptingSignatureState != SIGNATURESTATE_NOSIGNATURES || pImp->nDocumentSignatureState != SIGNATURESTATE_NOSIGNATURES );
1405 :
1406 : // the target ODF version on saving
1407 0 : SvtSaveOptions aSaveOpt;
1408 0 : SvtSaveOptions::ODFDefaultVersion nVersion = aSaveOpt.GetODFDefaultVersion();
1409 :
1410 : // the document is not new and is not modified
1411 0 : OUString aODFVersion;
1412 : try
1413 : {
1414 : // check the version of the document
1415 0 : uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
1416 0 : xPropSet->getPropertyValue("Version") >>= aODFVersion;
1417 : }
1418 0 : catch( uno::Exception& )
1419 : {}
1420 :
1421 0 : bool bNoSig = false;
1422 :
1423 0 : if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty()
1424 0 : || (!aODFVersion.equals( ODFVER_012_TEXT ) && !bHasSign) )
1425 : {
1426 : // the document might need saving ( new, modified or in ODF1.1 format without signature )
1427 :
1428 0 : if ( nVersion >= SvtSaveOptions::ODFVER_012 )
1429 : {
1430 :
1431 0 : if ( (bHasSign && MessageDialog(NULL, SfxResId(STR_XMLSEC_QUERY_SAVESIGNEDBEFORESIGN), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO).Execute() == RET_YES)
1432 0 : || (!bHasSign && MessageDialog(NULL, SfxResId(RID_SVXSTR_XMLSEC_QUERY_SAVEBEFORESIGN), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO).Execute() == RET_YES) )
1433 : {
1434 0 : sal_uInt16 nId = SID_SAVEDOC;
1435 0 : if ( !GetMedium() || GetMedium()->GetName().isEmpty() )
1436 0 : nId = SID_SAVEASDOC;
1437 0 : SfxRequest aSaveRequest( nId, SfxCallMode::SLOT, GetPool() );
1438 : //ToDo: Review. We needed to call SetModified, otherwise the document would not be saved.
1439 0 : SetModified(true);
1440 0 : ExecFile_Impl( aSaveRequest );
1441 :
1442 : // Check if it is stored in OASIS format...
1443 0 : if ( GetMedium() && GetMedium()->GetFilter()
1444 0 : && ( !GetMedium()->GetFilter()->IsOwnFormat() || !GetMedium()->HasStorage_Impl()
1445 0 : || SotStorage::GetVersion( GetMedium()->GetStorage() ) <= SOFFICE_FILEFORMAT_60 ) )
1446 : {
1447 : // Only OASIS format will be handled further
1448 0 : MessageDialog( NULL, SfxResId( STR_INFO_WRONGDOCFORMAT ), VCL_MESSAGE_INFO ).Execute();
1449 0 : return;
1450 0 : }
1451 : }
1452 : else
1453 : {
1454 : // When the document is modified then we must not show the
1455 : // digital signatures dialog
1456 : // If we have come here then the user denied to save.
1457 0 : if (!bHasSign)
1458 0 : bNoSig = true;
1459 : }
1460 : }
1461 : else
1462 : {
1463 0 : MessageDialog(NULL, SfxResId(STR_XMLSEC_ODF12_EXPECTED)).Execute();
1464 0 : return;
1465 : }
1466 :
1467 0 : if ( IsModified() || !GetMedium() || GetMedium()->GetName().isEmpty() )
1468 0 : return;
1469 : }
1470 :
1471 : // the document is not modified currently, so it can not become modified after signing
1472 0 : bool bAllowModifiedBack = false;
1473 0 : if ( IsEnableSetModified() )
1474 : {
1475 0 : EnableSetModified( false );
1476 0 : bAllowModifiedBack = true;
1477 : }
1478 :
1479 : // we have to store to the original document, the original medium should be closed for this time
1480 0 : if ( !bNoSig
1481 0 : && ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium ) )
1482 : {
1483 0 : GetMedium()->CloseAndRelease();
1484 :
1485 : // We sign only ODF1.2, that means that if this point has been reached,
1486 : // the ODF1.2 signing process should be used.
1487 : // This code still might be called to show the signature of ODF1.1 document.
1488 : bool bSigned = GetMedium()->SignContents_Impl(
1489 : bScriptingContent,
1490 : aODFVersion,
1491 0 : pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_OK
1492 0 : || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED
1493 0 : || pImp->nDocumentSignatureState == SIGNATURESTATE_SIGNATURES_PARTIAL_OK);
1494 :
1495 0 : DoSaveCompleted( GetMedium() );
1496 :
1497 0 : if ( bSigned )
1498 : {
1499 0 : if ( bScriptingContent )
1500 : {
1501 0 : pImp->nScriptingSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1502 :
1503 : // adding of scripting signature removes existing document signature
1504 0 : pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1505 : }
1506 : else
1507 0 : pImp->nDocumentSignatureState = SIGNATURESTATE_UNKNOWN;// Re-Check
1508 :
1509 0 : pImp->bSignatureErrorIsShown = false;
1510 :
1511 0 : Invalidate( SID_SIGNATURE );
1512 0 : Invalidate( SID_MACRO_SIGNATURE );
1513 0 : Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
1514 : }
1515 : }
1516 :
1517 0 : if ( bAllowModifiedBack )
1518 0 : EnableSetModified( true );
1519 : }
1520 :
1521 34398 : sal_uInt16 SfxObjectShell::GetDocumentSignatureState()
1522 : {
1523 34398 : return ImplGetSignatureState( false );
1524 : }
1525 :
1526 0 : void SfxObjectShell::SignDocumentContent()
1527 : {
1528 0 : ImplSign( false );
1529 0 : }
1530 :
1531 0 : sal_uInt16 SfxObjectShell::GetScriptingSignatureState()
1532 : {
1533 0 : return ImplGetSignatureState( true );
1534 : }
1535 :
1536 0 : void SfxObjectShell::SignScriptingContent()
1537 : {
1538 0 : ImplSign( true );
1539 0 : }
1540 :
1541 : namespace
1542 : {
1543 : class theSfxObjectShellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSfxObjectShellUnoTunnelId > {};
1544 : }
1545 :
1546 133936 : const uno::Sequence<sal_Int8>& SfxObjectShell::getUnoTunnelId()
1547 : {
1548 133936 : return theSfxObjectShellUnoTunnelId::get().getSeq();
1549 951 : }
1550 :
1551 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|