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