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