Branch libreoffice-5-0-4
[LibreOffice.git] / sfx2 / source / doc / objxtor.cxx
blob526f66e5f64a2f3ce89a6321f21783159745735c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include "arrdecl.hxx"
23 #include <map>
25 #include <cppuhelper/implbase1.hxx>
27 #include <com/sun/star/util/XCloseable.hpp>
28 #include <com/sun/star/frame/XComponentLoader.hpp>
29 #include <com/sun/star/frame/Desktop.hpp>
30 #include <com/sun/star/util/XCloseBroadcaster.hpp>
31 #include <com/sun/star/util/XCloseListener.hpp>
32 #include <com/sun/star/util/XModifyBroadcaster.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/frame/XTitle.hpp>
35 #include <osl/mutex.hxx>
36 #include <rtl/instance.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <vcl/wrkwin.hxx>
39 #include <vcl/svapp.hxx>
40 #include <svl/eitem.hxx>
41 #include <tools/rtti.hxx>
42 #include <svl/lstner.hxx>
43 #include <sfx2/sfxhelp.hxx>
44 #include <basic/sbstar.hxx>
45 #include <svl/stritem.hxx>
46 #include <basic/sbx.hxx>
47 #include <unotools/eventcfg.hxx>
49 #include <sfx2/objsh.hxx>
50 #include <sfx2/signaturestate.hxx>
51 #include <sfx2/sfxmodelfactory.hxx>
53 #include <basic/sbuno.hxx>
54 #include <svtools/sfxecode.hxx>
55 #include <svtools/ehdl.hxx>
56 #include <unotools/printwarningoptions.hxx>
57 #include <comphelper/processfactory.hxx>
58 #include <comphelper/string.hxx>
60 #include <com/sun/star/document/XStorageBasedDocument.hpp>
61 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
62 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
63 #include <com/sun/star/document/XEmbeddedScripts.hpp>
64 #include <com/sun/star/document/XScriptInvocationContext.hpp>
66 #include <svl/urihelper.hxx>
67 #include <unotools/pathoptions.hxx>
68 #include <svl/sharecontrolfile.hxx>
69 #include <unotools/localfilehelper.hxx>
70 #include <unotools/ucbhelper.hxx>
71 #include <svtools/asynclink.hxx>
72 #include <tools/diagnose_ex.h>
73 #include <comphelper/classids.hxx>
75 #include <sfx2/app.hxx>
76 #include <sfx2/docfac.hxx>
77 #include <sfx2/docfile.hxx>
78 #include <sfx2/event.hxx>
79 #include <sfx2/dispatch.hxx>
80 #include <sfx2/viewsh.hxx>
81 #include <sfx2/viewfrm.hxx>
82 #include <sfx2/sfxresid.hxx>
83 #include "objshimp.hxx"
84 #include "sfxtypes.hxx"
85 #include <sfx2/evntconf.hxx>
86 #include <sfx2/request.hxx>
87 #include "doc.hrc"
88 #include "sfxlocal.hrc"
89 #include "appdata.hxx"
90 #include <sfx2/sfxsids.hrc>
91 #include <basic/basmgr.hxx>
92 #include <svtools/svtools.hrc>
93 #include <sfx2/QuerySaveDocument.hxx>
94 #include "helpid.hrc"
95 #include <sfx2/msg.hxx>
96 #include "appbaslib.hxx"
97 #include <sfx2/sfxbasemodel.hxx>
98 #include <shellimpl.hxx>
100 #include <basic/basicmanagerrepository.hxx>
102 using namespace ::com::sun::star;
103 using namespace ::com::sun::star::uno;
104 using namespace ::com::sun::star::script;
105 using namespace ::com::sun::star::frame;
106 using namespace ::com::sun::star::document;
108 using ::basic::BasicManagerRepository;
109 #include <uno/mapping.hxx>
111 #include "sfxslots.hxx"
113 namespace {
115 class theCurrentComponent : public rtl::Static< WeakReference< XInterface >, theCurrentComponent > {};
117 #if HAVE_FEATURE_SCRIPTING
119 // remember all registered components for VBA compatibility, to be able to remove them on disposing the model
120 typedef ::std::map< XInterface*, OString > VBAConstantNameMap;
121 static VBAConstantNameMap s_aRegisteredVBAConstants;
123 OString lclGetVBAGlobalConstName( const Reference< XInterface >& rxComponent )
125 OSL_ENSURE( rxComponent.is(), "lclGetVBAGlobalConstName - missing component" );
127 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( rxComponent.get() );
128 if( aIt != s_aRegisteredVBAConstants.end() )
129 return aIt->second;
131 uno::Reference< beans::XPropertySet > xProps( rxComponent, uno::UNO_QUERY );
132 if( xProps.is() ) try
134 OUString aConstName;
135 xProps->getPropertyValue("VBAGlobalConstantName") >>= aConstName;
136 return OUStringToOString( aConstName, RTL_TEXTENCODING_ASCII_US );
138 catch (const uno::Exception&) // not supported
141 return OString();
144 #endif
146 } // namespace
150 class SfxModelListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
152 SfxObjectShell* mpDoc;
153 public:
154 explicit SfxModelListener_Impl( SfxObjectShell* pDoc ) : mpDoc(pDoc) {};
155 virtual void SAL_CALL queryClosing( const com::sun::star::lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
156 throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException, std::exception) SAL_OVERRIDE ;
157 virtual void SAL_CALL notifyClosing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
158 virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE ;
162 void SAL_CALL SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject& , sal_Bool )
163 throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException, std::exception)
167 void SAL_CALL SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject& ) throw ( com::sun::star::uno::RuntimeException, std::exception )
169 SolarMutexGuard aSolarGuard;
170 mpDoc->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING) );
173 void SAL_CALL SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject& _rEvent ) throw ( com::sun::star::uno::RuntimeException, std::exception )
175 // am I ThisComponent in AppBasic?
176 SolarMutexGuard aSolarGuard;
177 if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source )
179 // remove ThisComponent reference from AppBasic
180 SfxObjectShell::SetCurrentComponent( Reference< XInterface >() );
183 #if HAVE_FEATURE_SCRIPTING
184 /* Remove VBA component from AppBasic. As every application registers its
185 own current component, the disposed component may not be the "current
186 component" of the SfxObjectShell. */
187 if ( _rEvent.Source.is() )
189 VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( _rEvent.Source.get() );
190 if ( aIt != s_aRegisteredVBAConstants.end() )
192 if ( BasicManager* pAppMgr = SfxApplication::GetBasicManager() )
193 pAppMgr->SetGlobalUNOConstant( aIt->second.getStr(), Any( Reference< XInterface >() ) );
194 s_aRegisteredVBAConstants.erase( aIt );
197 #endif
199 if ( !mpDoc->Get_Impl()->bClosing )
200 // GCC crashes when already in the destructor, so first query the Flag
201 mpDoc->DoClose();
204 TYPEINIT1(SfxObjectShell, SfxShell);
207 SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell )
208 :mpObjectContainer(0)
209 ,rDocShell( _rDocShell )
210 ,aMacroMode( *this )
211 ,pProgress( 0)
212 ,nTime( DateTime::SYSTEM )
213 ,nVisualDocumentNumber( USHRT_MAX)
214 ,nDocumentSignatureState( SignatureState::UNKNOWN )
215 ,nScriptingSignatureState( SignatureState::UNKNOWN )
216 ,bInList( false)
217 ,bClosing( false)
218 ,bIsSaving( false)
219 ,bPasswd( false)
220 ,bIsNamedVisible( false)
221 ,bIsTemplate(false)
222 ,bIsAbortingImport ( false)
223 ,bImportDone ( false)
224 ,bInPrepareClose( false )
225 ,bPreparedForClose( false )
226 ,bForbidReload( false )
227 ,bBasicInitialized( false )
228 ,bIsPrintJobCancelable( true )
229 ,bOwnsStorage( true )
230 ,bNoBaseURL( false )
231 ,bInitialized( false )
232 ,bSignatureErrorIsShown( false )
233 ,bModelInitialized( false )
234 ,bPreserveVersions( true )
235 ,m_bMacroSignBroken( false )
236 ,m_bNoBasicCapabilities( false )
237 ,m_bDocRecoverySupport( true )
238 ,bQueryLoadTemplate( true )
239 ,bLoadReadonly( false )
240 ,bUseUserData( true )
241 ,bSaveVersionOnClose( false )
242 ,m_bSharedXMLFlag( false )
243 ,m_bAllowShareControlFileClean( true )
244 ,m_bConfigOptionsChecked( false )
245 ,lErr(ERRCODE_NONE)
246 ,nEventId ( 0)
247 ,pReloadTimer ( 0)
248 ,pMarkData( 0 )
249 ,nLoadedFlags ( SfxLoadedFlags::ALL )
250 ,nFlagsInProgress( SfxLoadedFlags::NONE )
251 ,bModalMode( false )
252 ,bRunningMacro( false )
253 ,bReloadAvailable( false )
254 ,nAutoLoadLocks( 0 )
255 ,pModule( 0 )
256 ,eFlags( SfxObjectShellFlags::UNDEFINED )
257 ,bReadOnlyUI( false )
258 ,nStyleFilter( 0 )
259 ,bDisposing( false )
260 ,m_bEnableSetModified( true )
261 ,m_bIsModified( false )
262 ,m_nMapUnit( MAP_100TH_MM )
263 ,m_bCreateTempStor( false )
264 ,m_bIsInit( false )
265 ,m_bIncomplEncrWarnShown( false )
266 ,m_nModifyPasswordHash( 0 )
267 ,m_bModifyPasswordEntered( false )
269 SfxObjectShell* pDoc = &_rDocShell;
270 SfxObjectShellArr_Impl &rArr = SfxGetpApp()->GetObjectShells_Impl();
271 rArr.push_back( pDoc );
272 bInList = true;
277 SfxObjectShell_Impl::~SfxObjectShell_Impl()
283 SfxObjectShell::SfxObjectShell( const SfxModelFlags i_nCreationFlags )
284 : pImp( new SfxObjectShell_Impl( *this ) )
285 , pMedium(0)
286 , pStyleSheetPool(0)
287 , eCreateMode(SfxObjectCreateMode::STANDARD)
288 , bHasName( false )
289 , bIsInGenerateThumbnail ( false )
291 if (i_nCreationFlags & SfxModelFlags::EMBEDDED_OBJECT)
292 eCreateMode = SfxObjectCreateMode::EMBEDDED;
293 else if (i_nCreationFlags & SfxModelFlags::EXTERNAL_LINK)
294 eCreateMode = SfxObjectCreateMode::INTERNAL;
296 const bool bScriptSupport = ( i_nCreationFlags & SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS ) == SfxModelFlags::NONE;
297 if ( !bScriptSupport )
298 SetHasNoBasic();
300 const bool bDocRecovery = ( i_nCreationFlags & SfxModelFlags::DISABLE_DOCUMENT_RECOVERY ) == SfxModelFlags::NONE;
301 if ( !bDocRecovery )
302 pImp->m_bDocRecoverySupport = false;
307 // initializes a document from a file-description
309 SfxObjectShell::SfxObjectShell
311 SfxObjectCreateMode eMode /* Purpose, io which the SfxObjectShell
312 is created:
314 SfxObjectCreateMode::EMBEDDED (default)
315 as SO-Server from within another
316 Document
318 SfxObjectCreateMode::STANDARD,
319 as a normal Document open stand-alone
321 SfxObjectCreateMode::PREVIEW
322 to enable a Preview, if possible are
323 only little information is needed
325 SfxObjectCreateMode::ORGANIZER
326 to be displayed in the Organizer, here
327 notning of the contents is used */
330 /* [Description]
332 Constructor of the class SfxObjectShell.
335 : pImp( new SfxObjectShell_Impl( *this ) ),
336 pMedium(0),
337 pStyleSheetPool(0),
338 eCreateMode(eMode),
339 bHasName( false ),
340 bIsInGenerateThumbnail ( false )
346 // virtual destructor of typical base-class SfxObjectShell
348 SfxObjectShell::~SfxObjectShell()
351 if ( IsEnableSetModified() )
352 EnableSetModified( false );
354 // Never call GetInPlaceObject(), the access to the derivative branch
355 // SfxInternObject is not allowed because of a compiler bug
356 SfxObjectShell::CloseInternal();
357 pImp->pBaseModel.set( NULL );
359 DELETEX(AutoReloadTimer_Impl, pImp->pReloadTimer );
361 SfxApplication *pSfxApp = SfxGetpApp();
362 if ( USHRT_MAX != pImp->nVisualDocumentNumber )
363 pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
365 // Destroy Basic-Manager
366 pImp->aBasicManager.reset( NULL );
368 if ( pSfxApp->GetDdeService() )
369 pSfxApp->RemoveDdeTopic( this );
371 pImp->pBaseModel.set( NULL );
373 // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
374 if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( false ) == pImp->m_xDocStorage )
375 pMedium->CanDisposeStorage_Impl( false );
377 if ( pImp->mpObjectContainer )
379 pImp->mpObjectContainer->CloseEmbeddedObjects();
380 delete pImp->mpObjectContainer;
383 if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() )
384 pImp->m_xDocStorage->dispose();
386 if ( pMedium )
388 pMedium->CloseAndReleaseStreams_Impl();
390 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
391 if ( IsDocShared() )
392 FreeSharedFile();
393 #endif
394 DELETEX( SfxMedium, pMedium );
397 // The removing of the temporary file must be done as the latest step in the document destruction
398 if ( !pImp->aTempName.isEmpty() )
400 OUString aTmp;
401 ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp );
402 ::utl::UCBContentHelper::Kill( aTmp );
405 delete pImp;
410 void SfxObjectShell::Stamp_SetPrintCancelState(bool bState)
412 pImp->bIsPrintJobCancelable = bState;
417 bool SfxObjectShell::Stamp_GetPrintCancelState() const
419 return pImp->bIsPrintJobCancelable;
424 // closes the Object and all its views
426 bool SfxObjectShell::Close()
428 SfxObjectShellRef aRef(this);
429 return CloseInternal();
432 // variant that does not take a reference to itself, so we can call it during object destruction
433 bool SfxObjectShell::CloseInternal()
435 if ( !pImp->bClosing )
437 // Do not close if a progress is still running
438 if ( !pImp->bDisposing && GetProgress() )
439 return false;
441 pImp->bClosing = true;
442 Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY );
444 if ( xCloseable.is() )
448 xCloseable->close( sal_True );
450 catch (const Exception&)
452 pImp->bClosing = false;
456 if ( pImp->bClosing )
458 // remove from Document list
459 // If there is no App, there is no document to remove
460 // no need to call GetOrCreate here
461 SfxApplication *pSfxApp = SfxApplication::Get();
462 if(pSfxApp)
464 SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl();
465 SfxObjectShellArr_Impl::iterator it = std::find( rDocs.begin(), rDocs.end(), this );
466 if ( it != rDocs.end() )
467 rDocs.erase( it );
468 pImp->bInList = false;
473 return true;
476 OUString SfxObjectShell::CreateShellID( const SfxObjectShell* pShell )
478 if (!pShell)
479 return OUString();
481 OUString aShellID;
483 SfxMedium* pMedium = pShell->GetMedium();
484 if (pMedium)
485 aShellID = pMedium->GetBaseURL();
487 if (!aShellID.isEmpty())
488 return aShellID;
490 sal_Int64 nShellID = reinterpret_cast<sal_Int64>(pShell);
491 aShellID = "0x" + OUString::number(nShellID, 16);
492 return aShellID;
495 // returns a pointer the first SfxDocument of specified type
497 SfxObjectShell* SfxObjectShell::GetFirst
499 const TypeId* pType ,
500 bool bOnlyVisible
503 SfxObjectShellArr_Impl &rDocs = SfxGetpApp()->GetObjectShells_Impl();
505 // search for a SfxDocument of the specified type
506 for ( sal_uInt16 nPos = 0; nPos < rDocs.size(); ++nPos )
508 SfxObjectShell* pSh = rDocs[ nPos ];
509 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
510 continue;
512 if ( ( !pType || pSh->IsA(*pType) ) &&
513 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, true )))
514 return pSh;
517 return 0;
521 // returns a pointer to the next SfxDocument of specified type behind *pDoc
523 SfxObjectShell* SfxObjectShell::GetNext
525 const SfxObjectShell& rPrev,
526 const TypeId* pType,
527 bool bOnlyVisible
530 SfxObjectShellArr_Impl &rDocs = SfxGetpApp()->GetObjectShells_Impl();
532 // refind the specified predecessor
533 sal_uInt16 nPos;
534 for ( nPos = 0; nPos < rDocs.size(); ++nPos )
535 if ( rDocs[nPos] == &rPrev )
536 break;
538 // search for the next SfxDocument of the specified type
539 for ( ++nPos; nPos < rDocs.size(); ++nPos )
541 SfxObjectShell* pSh = rDocs[ nPos ];
542 if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
543 continue;
545 if ( ( !pType || pSh->IsA(*pType) ) &&
546 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, true )))
547 return pSh;
549 return 0;
554 SfxObjectShell* SfxObjectShell::Current()
556 SfxViewFrame *pFrame = SfxViewFrame::Current();
557 return pFrame ? pFrame->GetObjectShell() : 0;
562 bool SfxObjectShell::IsInPrepareClose() const
564 return pImp->bInPrepareClose;
569 struct BoolEnv_Impl
571 SfxObjectShell_Impl* pImp;
572 explicit BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP )
573 { pImpP->bInPrepareClose = true; }
574 ~BoolEnv_Impl() { pImp->bInPrepareClose = false; }
578 bool SfxObjectShell::PrepareClose
580 bool bUI // true: Dialog and so on is allowed
581 // false: silent-mode
584 if( pImp->bInPrepareClose || pImp->bPreparedForClose )
585 return true;
586 BoolEnv_Impl aBoolEnv( pImp );
588 // DocModalDialog?
589 if ( IsInModalMode() )
590 return false;
592 SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this );
593 if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI ) )
594 return false;
596 // prepare views for closing
597 for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
598 pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) )
600 DBG_ASSERT(pFrm->GetViewShell(),"No Shell");
601 if ( pFrm->GetViewShell() )
603 bool nRet = pFrm->GetViewShell()->PrepareClose( bUI );
604 if ( !nRet )
605 return nRet;
609 SfxApplication *pSfxApp = SfxGetpApp();
610 pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(GlobalEventId::PREPARECLOSEDOC), this) );
612 if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED )
614 pImp->bPreparedForClose = true;
615 return true;
618 // Ask if possible if it should be saved
619 // only ask for the Document in the visible window
620 SfxViewFrame *pFrame = SfxObjectShell::Current() == this
621 ? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );
623 if ( bUI && IsModified() && pFrame )
625 // restore minimized
626 SfxFrame& rTop = pFrame->GetTopFrame();
627 SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() );
628 pFrame->GetFrame().Appear();
630 // Ask if to save
631 short nRet = RET_YES;
633 const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW );
634 const OUString sTitle = xTitle->getTitle ();
635 nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle);
637 /*HACK for plugin::destroy()*/
639 if ( RET_YES == nRet )
641 // Save by each Dispatcher
642 const SfxPoolItem *pPoolItem;
643 if ( IsSaveVersionOnClose() )
645 SfxStringItem aItem( SID_DOCINFO_COMMENTS, SfxResId(STR_AUTOMATICVERSION).toString() );
646 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
647 const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 };
648 pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
650 else
652 SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
653 const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 };
654 pPoolItem = pFrame->GetBindings().ExecuteSynchron( IsReadOnlyMedium() ? SID_SAVEASDOC : SID_SAVEDOC, ppArgs );
657 if ( !pPoolItem || pPoolItem->ISA(SfxVoidItem) || ( pPoolItem->ISA(SfxBoolItem) && !static_cast<const SfxBoolItem*>( pPoolItem )->GetValue() ) )
658 return false;
660 else if ( RET_CANCEL == nRet )
661 // Cancelled
662 return false;
665 pImp->bPreparedForClose = true;
666 return true;
670 #if HAVE_FEATURE_SCRIPTING
671 namespace
673 static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument )
675 if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities )
677 if ( !_rDocument.Get_Impl()->bBasicInitialized )
678 const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl();
679 return _rDocument.Get_Impl()->aBasicManager.get();
682 // assume we do not have Basic ourself, but we can refer to another
683 // document which does (by our model's XScriptInvocationContext::getScriptContainer).
684 // In this case, we return the BasicManager of this other document.
686 OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(),
687 "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
688 Reference< XModel > xForeignDocument;
689 Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY );
690 if ( xContext.is() )
692 xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY );
693 OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(),
694 "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
697 BasicManager* pBasMgr = NULL;
698 if ( xForeignDocument.is() )
699 pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument );
701 return pBasMgr;
704 #endif
706 BasicManager* SfxObjectShell::GetBasicManager() const
708 BasicManager* pBasMgr = NULL;
709 #if HAVE_FEATURE_SCRIPTING
712 pBasMgr = lcl_getBasicManagerForDocument( *this );
713 if ( !pBasMgr )
714 pBasMgr = SfxApplication::GetBasicManager();
716 catch (const css::ucb::ContentCreationException& e)
718 SAL_WARN("sfx.doc", "caught exception " << e.Message);
720 #endif
721 return pBasMgr;
724 void SfxObjectShell::SetHasNoBasic()
726 pImp->m_bNoBasicCapabilities = true;
729 bool SfxObjectShell::HasBasic() const
731 #if !HAVE_FEATURE_SCRIPTING
732 return false;
733 #else
734 if ( pImp->m_bNoBasicCapabilities )
735 return false;
737 if ( !pImp->bBasicInitialized )
738 const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl();
740 return pImp->aBasicManager.isValid();
741 #endif
745 #if HAVE_FEATURE_SCRIPTING
746 namespace
748 const Reference< XLibraryContainer >&
749 lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer,
750 const Reference< XModel >& _rxDocument )
752 if ( !_rxContainer.is() )
756 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY );
757 const Reference< XComponentContext > xContext(
758 ::comphelper::getProcessComponentContext() );
759 _rxContainer.set ( _bScript
760 ? DocumentScriptLibraryContainer::create(
761 xContext, xStorageDoc )
762 : DocumentDialogLibraryContainer::create(
763 xContext, xStorageDoc )
764 , UNO_QUERY_THROW );
766 catch (const Exception&)
768 DBG_UNHANDLED_EXCEPTION();
771 return _rxContainer;
774 #endif
776 Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer()
778 #if HAVE_FEATURE_SCRIPTING
781 if ( !pImp->m_bNoBasicCapabilities )
782 return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() );
784 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
785 if ( pBasMgr )
786 return pBasMgr->GetDialogLibraryContainer().get();
788 catch (const css::ucb::ContentCreationException& e)
790 SAL_WARN("sfx.doc", "caught exception " << e.Message);
793 SAL_WARN("sfx.doc", "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?");
794 #endif
795 return SfxGetpApp()->GetDialogContainer();
798 Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer()
800 #if HAVE_FEATURE_SCRIPTING
803 if ( !pImp->m_bNoBasicCapabilities )
804 return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() );
806 BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
807 if ( pBasMgr )
808 return pBasMgr->GetScriptLibraryContainer().get();
810 catch (const css::ucb::ContentCreationException& e)
812 SAL_WARN("sfx.doc", "caught exception " << e.Message);
814 SAL_WARN("sfx.doc", "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?");
815 #endif
816 return SfxGetpApp()->GetBasicContainer();
819 StarBASIC* SfxObjectShell::GetBasic() const
821 #if !HAVE_FEATURE_SCRIPTING
822 return NULL;
823 #else
824 BasicManager * pMan = GetBasicManager();
825 return pMan ? pMan->GetLib(0) : NULL;
826 #endif
829 void SfxObjectShell::InitBasicManager_Impl()
830 /* [Description]
832 Creates a document's BasicManager and loads it, if we are already based on
833 a storage.
835 [Note]
837 This method has to be called by implementations of <SvPersist::Load()>
838 (with its pStor parameter) and by implementations of <SvPersist::InitNew()>
839 (with pStor = 0).
843 /* #163556# (DR) - Handling of recursive calls while creating the Bacic
844 manager.
846 It is possible that (while creating the Basic manager) the code that
847 imports the Basic storage wants to access the Basic manager again.
848 Especially in VBA compatibility mode, there is code that wants to
849 access the "VBA Globals" object which is stored as global UNO constant
850 in the Basic manager.
852 To achieve correct handling of the recursive calls of this function
853 from lcl_getBasicManagerForDocument(), the implementation of the
854 function BasicManagerRepository::getDocumentBasicManager() has been
855 changed to return the Basic manager currently under construction, when
856 called repeatedly.
858 The variable pImp->bBasicInitialized will be set to sal_True after
859 construction now, to ensure that the recursive call of the function
860 lcl_getBasicManagerForDocument() will be routed into this function too.
862 Calling BasicManagerHolder::reset() twice is not a big problem, as it
863 does not take ownership but stores only the raw pointer. Owner of all
864 Basic managers is the global BasicManagerRepository instance.
866 #if HAVE_FEATURE_SCRIPTING
867 DBG_ASSERT( !pImp->bBasicInitialized && !pImp->aBasicManager.isValid(), "Lokaler BasicManager bereits vorhanden");
870 pImp->aBasicManager.reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
872 catch (const css::ucb::ContentCreationException& e)
874 SAL_WARN("sfx.doc", "caught exception " << e.Message);
876 DBG_ASSERT( pImp->aBasicManager.isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
877 pImp->bBasicInitialized = true;
878 #endif
883 bool SfxObjectShell::DoClose()
885 return Close();
890 SfxObjectShell* SfxObjectShell::GetObjectShell()
892 return this;
897 uno::Sequence< OUString > SfxObjectShell::GetEventNames()
899 static uno::Sequence< OUString >* pEventNameContainer = NULL;
901 if ( !pEventNameContainer )
903 SolarMutexGuard aGuard;
904 if ( !pEventNameContainer )
906 static uno::Sequence< OUString > aEventNameContainer = GlobalEventConfig().getElementNames();
907 pEventNameContainer = &aEventNameContainer;
911 return *pEventNameContainer;
916 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const
918 return GetBaseModel();
921 void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel )
923 OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" );
924 pImp->pBaseModel.set( pModel );
925 if ( pImp->pBaseModel.is() )
927 pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) );
933 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const
935 return pImp->pBaseModel.get();
938 void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet)
940 pImp->nStyleFilter = nSet;
943 sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex()
945 return pImp->nStyleFilter;
949 void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent )
951 WeakReference< XInterface >& rTheCurrentComponent = theCurrentComponent::get();
953 Reference< XInterface > xOldCurrentComp(rTheCurrentComponent);
954 if ( _rxComponent == xOldCurrentComp )
955 // nothing to do
956 return;
957 // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
958 // /required/ for "_rxComponent == s_xCurrentComponent.get()".
959 // In other words, it's still possible that we here do something which is not necessary,
960 // but we should have filtered quite some unnecessary calls already.
962 #if HAVE_FEATURE_SCRIPTING
963 BasicManager* pAppMgr = SfxApplication::GetBasicManager();
964 rTheCurrentComponent = _rxComponent;
965 if ( pAppMgr )
967 // set "ThisComponent" for Basic
968 pAppMgr->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent ) );
970 // set new current component for VBA compatibility
971 if ( _rxComponent.is() )
973 OString aVBAConstName = lclGetVBAGlobalConstName( _rxComponent );
974 if ( !aVBAConstName.isEmpty() )
976 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( _rxComponent ) );
977 s_aRegisteredVBAConstants[ _rxComponent.get() ] = aVBAConstName;
980 // no new component passed -> remove last registered VBA component
981 else if ( xOldCurrentComp.is() )
983 OString aVBAConstName = lclGetVBAGlobalConstName( xOldCurrentComp );
984 if ( !aVBAConstName.isEmpty() )
986 pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( Reference< XInterface >() ) );
987 s_aRegisteredVBAConstants.erase( xOldCurrentComp.get() );
991 #endif
994 Reference< XInterface > SfxObjectShell::GetCurrentComponent()
996 return theCurrentComponent::get();
1000 OUString SfxObjectShell::GetServiceNameFromFactory( const OUString& rFact )
1002 //! Remove everything behind name!
1003 OUString aFact( rFact );
1004 OUString aPrefix("private:factory/");
1005 if ( aFact.startsWith( aPrefix ) )
1006 aFact = aFact.copy( aPrefix.getLength() );
1007 sal_Int32 nPos = aFact.indexOf( '?' );
1008 OUString aParam;
1009 if ( nPos != -1 )
1011 aParam = aFact.copy( nPos );
1012 aFact = aFact.copy( 0, nPos );
1013 aParam = aParam.copy(1);
1015 aFact = comphelper::string::remove(aFact, '4');
1016 aFact = aFact.toAsciiLowerCase();
1018 // HACK: sometimes a real document service name is given here instead of
1019 // a factory short name. Set return value directly to this service name as fallback
1020 // in case next lines of code does nothing ...
1021 // use rFact instead of normed aFact value !
1022 OUString aServiceName = rFact;
1024 if ( aFact == "swriter" )
1026 aServiceName = "com.sun.star.text.TextDocument";
1028 else if ( aFact == "sweb" || aFact == "swriter/web" )
1030 aServiceName = "com.sun.star.text.WebDocument";
1032 else if ( aFact == "sglobal" || aFact == "swriter/globaldocument" )
1034 aServiceName = "com.sun.star.text.GlobalDocument";
1036 else if ( aFact == "scalc" )
1038 aServiceName = "com.sun.star.sheet.SpreadsheetDocument";
1040 else if ( aFact == "sdraw" )
1042 aServiceName = "com.sun.star.drawing.DrawingDocument";
1044 else if ( aFact == "simpress" )
1046 aServiceName = "com.sun.star.presentation.PresentationDocument";
1048 else if ( aFact == "schart" )
1050 aServiceName = "com.sun.star.chart.ChartDocument";
1052 else if ( aFact == "smath" )
1054 aServiceName = "com.sun.star.formula.FormulaProperties";
1056 #if HAVE_FEATURE_SCRIPTING
1057 else if ( aFact == "sbasic" )
1059 aServiceName = "com.sun.star.script.BasicIDE";
1061 #endif
1062 #if HAVE_FEATURE_DBCONNECTIVITY
1063 else if ( aFact == "sdatabase" )
1065 aServiceName = "com.sun.star.sdb.OfficeDatabaseDocument";
1067 #endif
1069 return aServiceName;
1072 SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const OUString& rFact, SfxObjectCreateMode eMode )
1074 return CreateObject( GetServiceNameFromFactory( rFact ), eMode );
1078 SfxObjectShell* SfxObjectShell::CreateObject( const OUString& rServiceName, SfxObjectCreateMode eCreateMode )
1080 if ( !rServiceName.isEmpty() )
1082 uno::Reference < frame::XModel > xDoc( ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY );
1083 if ( xDoc.is() )
1085 uno::Reference < lang::XUnoTunnel > xObj( xDoc, UNO_QUERY );
1086 uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
1087 sal_Int64 nHandle = xObj->getSomething( aSeq );
1088 if ( nHandle )
1090 SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
1091 pRet->SetCreateMode_Impl( eCreateMode );
1092 return pRet;
1097 return 0;
1100 Reference<lang::XComponent> SfxObjectShell::CreateAndLoadComponent( const SfxItemSet& rSet, SfxFrame* pFrame )
1102 uno::Sequence < beans::PropertyValue > aProps;
1103 TransformItems( SID_OPENDOC, rSet, aProps );
1104 SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME, false);
1105 SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME, false);
1106 OUString aURL;
1107 OUString aTarget("_blank");
1108 if ( pFileNameItem )
1109 aURL = pFileNameItem->GetValue();
1110 if ( pTargetItem )
1111 aTarget = pTargetItem->GetValue();
1113 uno::Reference < frame::XComponentLoader > xLoader;
1114 if ( pFrame )
1116 xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY );
1118 else
1119 xLoader = uno::Reference < frame::XComponentLoader >( frame::Desktop::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY );
1121 Reference <lang::XComponent> xComp;
1124 xComp = xLoader->loadComponentFromURL(aURL, aTarget, 0, aProps);
1126 catch (const uno::Exception&)
1130 return xComp;
1133 SfxObjectShell* SfxObjectShell::GetShellFromComponent( const Reference<lang::XComponent>& xComp )
1137 Reference<lang::XUnoTunnel> xTunnel(xComp, UNO_QUERY_THROW);
1138 Sequence <sal_Int8> aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
1139 sal_Int64 nHandle = xTunnel->getSomething( aSeq );
1140 if (!nHandle)
1141 return NULL;
1143 return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >( nHandle ));
1145 catch (const Exception&)
1149 return NULL;
1152 void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew )
1154 pImp->bInitialized = true;
1155 if ( i_fromInitNew )
1157 SetActivateEvent_Impl( SFX_EVENT_CREATEDOC );
1158 SfxGetpApp()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(GlobalEventId::DOCCREATED), this ) );
1160 else
1162 SfxGetpApp()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(GlobalEventId::LOADFINISHED), this ) );
1167 bool SfxObjectShell::IsChangeRecording() const
1169 // currently this function needs to be overwritten by Writer and Calc only
1170 DBG_ASSERT( false, "function not implemented" );
1171 return false;
1175 bool SfxObjectShell::HasChangeRecordProtection() const
1177 // currently this function needs to be overwritten by Writer and Calc only
1178 DBG_ASSERT( false, "function not implemented" );
1179 return false;
1183 void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ )
1185 // currently this function needs to be overwritten by Writer and Calc only
1186 DBG_ASSERT( false, "function not implemented" );
1190 bool SfxObjectShell::SetProtectionPassword( const OUString & /*rPassword*/ )
1192 // currently this function needs to be overwritten by Writer and Calc only
1193 DBG_ASSERT( false, "function not implemented" );
1194 return false;
1198 bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ )
1200 // currently this function needs to be overwritten by Writer and Calc only
1201 DBG_ASSERT( false, "function not implemented" );
1202 return false;
1205 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */