/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sfx2.hxx"

#include "arrdecl.hxx"
#include <map>

#include <cppuhelper/implbase1.hxx>

#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/util/XCloseBroadcaster.hpp>
#include <com/sun/star/util/XCloseListener.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XTitle.hpp>
#include <vos/mutex.hxx>

#include <tools/resary.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/svapp.hxx>
#include <svl/eitem.hxx>
#include <svl/lstner.hxx>
#include <sfx2/sfxhelp.hxx>
#include <basic/sbstar.hxx>
#include <svl/stritem.hxx>
#include <basic/sbx.hxx>
#include <unotools/eventcfg.hxx>

#include <sfx2/objsh.hxx>
#include <sfx2/signaturestate.hxx>
#include <sfx2/sfxmodelfactory.hxx>

#include <basic/sbuno.hxx>
#include <svtools/sfxecode.hxx>
#include <svtools/ehdl.hxx>
#include <unotools/printwarningoptions.hxx>
#include <comphelper/processfactory.hxx>

#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
#include <com/sun/star/document/XScriptInvocationContext.hpp>

#include <svl/urihelper.hxx>
#include <unotools/pathoptions.hxx>
#include <svl/sharecontrolfile.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/ucbhelper.hxx>
#include <svtools/asynclink.hxx>
#include <tools/diagnose_ex.h>
#include <sot/clsids.hxx>

#include <sfx2/app.hxx>
#include <sfx2/docfac.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/event.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/viewfrm.hxx>
#include "sfx2/sfxresid.hxx"
#include "objshimp.hxx"
#include "appbas.hxx"
#include "sfxtypes.hxx"
#include <sfx2/evntconf.hxx>
#include <sfx2/request.hxx>
#include "doc.hrc"
#include "sfxlocal.hrc"
#include "appdata.hxx"
#include <sfx2/appuno.hxx>
#include <sfx2/sfxsids.hrc>
#include "sfx2/basmgr.hxx"
#include "sfx2/QuerySaveDocument.hxx"
#include "helpid.hrc"
#include <sfx2/msg.hxx>
#include "appbaslib.hxx"
#include <sfx2/sfxbasemodel.hxx>

#include <basic/basicmanagerrepository.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::document;

using ::basic::BasicManagerRepository;
#include <uno/mapping.hxx>

//====================================================================

DBG_NAME(SfxObjectShell)

#define DocumentInfo
#include "sfxslots.hxx"

namespace {

static WeakReference< XInterface > s_xCurrentComponent;

// remember all registered components for VBA compatibility, to be able to remove them on disposing the model
typedef ::std::map< XInterface*, ::rtl::OString > VBAConstantNameMap;
static VBAConstantNameMap s_aRegisteredVBAConstants;

::rtl::OString lclGetVBAGlobalConstName( const Reference< XInterface >& rxComponent )
{
    OSL_ENSURE( rxComponent.is(), "lclGetVBAGlobalConstName - missing component" );

    VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( rxComponent.get() );
    if( aIt != s_aRegisteredVBAConstants.end() )
        return aIt->second;
    
    uno::Reference< beans::XPropertySet > xProps( rxComponent, uno::UNO_QUERY );
    if( xProps.is() ) try
    {
        ::rtl::OUString aConstName;
        xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VBAGlobalConstantName" ) ) ) >>= aConstName;
        return ::rtl::OUStringToOString( aConstName, RTL_TEXTENCODING_ASCII_US );
    }
    catch( uno::Exception& ) // not supported
    {
    }
    return ::rtl::OString();
}

} // namespace

//=========================================================================


//=========================================================================

class SfxModelListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XCloseListener >
{
    SfxObjectShell* mpDoc;
public:
    SfxModelListener_Impl( SfxObjectShell* pDoc ) : mpDoc(pDoc) {};
    virtual void SAL_CALL queryClosing( const com::sun::star::lang::EventObject& aEvent, sal_Bool bDeliverOwnership )
        throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException) ;
    virtual void SAL_CALL notifyClosing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ;
    virtual void SAL_CALL disposing( const com::sun::star::lang::EventObject& aEvent ) throw ( com::sun::star::uno::RuntimeException ) ;

};

void SAL_CALL SfxModelListener_Impl::queryClosing( const com::sun::star::lang::EventObject& , sal_Bool )
    throw ( com::sun::star::uno::RuntimeException, com::sun::star::util::CloseVetoException)
{
}

void SAL_CALL SfxModelListener_Impl::notifyClosing( const com::sun::star::lang::EventObject& ) throw ( com::sun::star::uno::RuntimeException )
{
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    mpDoc->Broadcast( SfxSimpleHint(SFX_HINT_DEINITIALIZING) );
}

void SAL_CALL SfxModelListener_Impl::disposing( const com::sun::star::lang::EventObject& _rEvent ) throw ( com::sun::star::uno::RuntimeException )
{
    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

    // am I ThisComponent in AppBasic?
    if ( SfxObjectShell::GetCurrentComponent() == _rEvent.Source )
    {
        // remove ThisComponent reference from AppBasic
        SfxObjectShell::SetCurrentComponent( Reference< XInterface >() );
    }

    /*  Remove VBA component from AppBasic. As every application registers its
        own current component, the disposed component may not be the "current
        component" of the SfxObjectShell. */
    if ( _rEvent.Source.is() )
    {
        VBAConstantNameMap::iterator aIt = s_aRegisteredVBAConstants.find( _rEvent.Source.get() );
        if ( aIt != s_aRegisteredVBAConstants.end() )
        {
            if ( BasicManager* pAppMgr = SFX_APP()->GetBasicManager() )
                pAppMgr->SetGlobalUNOConstant( aIt->second.getStr(), Any( Reference< XInterface >() ) );
            s_aRegisteredVBAConstants.erase( aIt );
        }
    }

    if ( !mpDoc->Get_Impl()->bClosing )
		// GCC stuerzt ab, wenn schon im dtor, also vorher Flag abfragen
        mpDoc->DoClose();
}

//--------------------------------------------------------------------
SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell )
    :mpObjectContainer(0)
    ,pBasicManager( new SfxBasicManagerHolder )
    ,rDocShell( _rDocShell )
    ,aMacroMode( *this )
    ,pProgress( 0)
    ,nTime()
    ,nVisualDocumentNumber( USHRT_MAX)
    ,nDocumentSignatureState( SIGNATURESTATE_UNKNOWN )
    ,nScriptingSignatureState( SIGNATURESTATE_UNKNOWN )
    ,bInList( sal_False)
    ,bClosing( sal_False)
    ,bIsSaving( sal_False)
    ,bPasswd( sal_False)
    ,bIsTmp( sal_False)
    ,bIsNamedVisible( sal_False)
    ,bIsTemplate(sal_False)
    ,bIsAbortingImport ( sal_False)
    ,bImportDone ( sal_False)
    ,bInPrepareClose( sal_False )
    ,bPreparedForClose( sal_False )
    ,bWaitingForPicklist( sal_True )
    ,bForbidReload( sal_False )
    ,bBasicInitialized( sal_False )
    ,bIsPrintJobCancelable( sal_True )
    ,bOwnsStorage( sal_True )
    ,bNoBaseURL( sal_False )
    ,bInitialized( sal_False )
    ,bSignatureErrorIsShown( sal_False )
    ,bModelInitialized( sal_False )
    ,bPreserveVersions( sal_True )
    ,m_bMacroSignBroken( sal_False )
    ,m_bNoBasicCapabilities( sal_False )
    ,m_bDocRecoverySupport( sal_True )
    ,bQueryLoadTemplate( sal_True )
    ,bLoadReadonly( sal_False )
    ,bUseUserData( sal_True )
    ,bSaveVersionOnClose( sal_False )
    ,m_bSharedXMLFlag( sal_False )
    ,m_bAllowShareControlFileClean( sal_True )
    ,lErr(ERRCODE_NONE)
    ,nEventId ( 0)
    ,pReloadTimer ( 0)
    ,pMarkData( 0 )
    ,nLoadedFlags ( SFX_LOADED_ALL )
    ,nFlagsInProgress( 0 )
    ,bModalMode( sal_False )
    ,bRunningMacro( sal_False )
    ,bReloadAvailable( sal_False )
    ,nAutoLoadLocks( 0 )
    ,pModule( 0 )
    ,eFlags( SFXOBJECTSHELL_UNDEFINED )
    ,bReadOnlyUI( sal_False )
    ,bHiddenLockedByAPI( sal_False )
    ,nStyleFilter( 0 )
    ,bDisposing( sal_False )
    ,m_bEnableSetModified( sal_True )
    ,m_bIsModified( sal_False )
    ,m_nMapUnit( MAP_100TH_MM )
    ,m_bCreateTempStor( sal_False )
    ,m_bIsInit( sal_False )
    ,m_bIncomplEncrWarnShown( sal_False )
    ,m_nModifyPasswordHash( 0 )
    ,m_bModifyPasswordEntered( sal_False )
{
	SfxObjectShell* pDoc = &_rDocShell;
	SfxObjectShellArr_Impl &rArr = SFX_APP()->GetObjectShells_Impl();
	rArr.C40_INSERT( SfxObjectShell, pDoc, rArr.Count() );
	bInList = sal_True;
}

//--------------------------------------------------------------------

SfxObjectShell_Impl::~SfxObjectShell_Impl()
{
    delete pBasicManager;
}

//--------------------------------------------------------------------

SfxObjectShell::SfxObjectShell( const sal_uInt64 i_nCreationFlags )
    :	pImp( new SfxObjectShell_Impl( *this ) )
    ,   pMedium(0)
    ,   pStyleSheetPool(0)
    ,   eCreateMode( ( i_nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD )
    ,   bHasName( sal_False )
{
	DBG_CTOR(SfxObjectShell, 0);

    const bool bScriptSupport = ( i_nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0;
    if ( !bScriptSupport )
        SetHasNoBasic();

    const bool bDocRecovery = ( i_nCreationFlags & SFXMODEL_DISABLE_DOCUMENT_RECOVERY ) == 0;
    if ( !bDocRecovery )
        pImp->m_bDocRecoverySupport = sal_False;
}

//--------------------------------------------------------------------

// initializes a document from a file-description

SfxObjectShell::SfxObjectShell
(
	SfxObjectCreateMode	eMode	/*	Zweck, zu dem die SfxObjectShell
									erzeugt wird:

									SFX_CREATE_MODE_EMBEDDED (default)
										als SO-Server aus einem anderen
										Dokument heraus

									SFX_CREATE_MODE_STANDARD,
										als normales, selbst"aendig ge"offnetes
										Dokument

									SFX_CREATE_MODE_PREVIEW
										um ein Preview durchzuf"uhren,
										ggf. werden weniger Daten ben"otigt

									SFX_CREATE_MODE_ORGANIZER
										um im Organizer dargestellt zu
										werden, hier werden keine Inhalte
										ben"otigt */
)

/*	[Beschreibung]

	Konstruktor der Klasse SfxObjectShell.
*/

:	pImp( new SfxObjectShell_Impl( *this ) ),
	pMedium(0),
	pStyleSheetPool(0),
    eCreateMode(eMode),
	bHasName( sal_False )
{
	DBG_CTOR(SfxObjectShell, 0);
}

//--------------------------------------------------------------------

// virtual dtor of typical base-class SfxObjectShell

SfxObjectShell::~SfxObjectShell()
{
	DBG_DTOR(SfxObjectShell, 0);

	if ( IsEnableSetModified() )
		EnableSetModified( sal_False );

	// Niemals GetInPlaceObject() aufrufen, der Zugriff auf den
	// Ableitungszweig SfxInternObject ist wegen eines Compiler Bugs nicht
	// erlaubt
	SfxObjectShell::Close();
    pImp->pBaseModel.set( NULL );

    DELETEX(pImp->pReloadTimer );

	SfxApplication *pSfxApp = SFX_APP();
	if ( USHRT_MAX != pImp->nVisualDocumentNumber )
		pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);

	// Basic-Manager zerst"oren
	pImp->pBasicManager->reset( NULL );

	if ( pSfxApp->GetDdeService() )
		pSfxApp->RemoveDdeTopic( this );

	pImp->pBaseModel.set( NULL );

    // don't call GetStorage() here, in case of Load Failure it's possible that a storage was never assigned!
    if ( pMedium && pMedium->HasStorage_Impl() && pMedium->GetStorage( sal_False ) == pImp->m_xDocStorage )
        pMedium->CanDisposeStorage_Impl( sal_False );

    if ( pImp->mpObjectContainer )
    {
        pImp->mpObjectContainer->CloseEmbeddedObjects();
        delete pImp->mpObjectContainer;
    }

    if ( pImp->bOwnsStorage && pImp->m_xDocStorage.is() )
    	pImp->m_xDocStorage->dispose();

	if ( pMedium )
	{
		pMedium->CloseAndReleaseStreams_Impl();

        if ( IsDocShared() )
            FreeSharedFile();

		DELETEX( pMedium );
	}

	// The removing of the temporary file must be done as the latest step in the document destruction
    if ( pImp->aTempName.Len() )
    {
        String aTmp;
        ::utl::LocalFileHelper::ConvertPhysicalNameToURL( pImp->aTempName, aTmp );
        ::utl::UCBContentHelper::Kill( aTmp );
    }

    delete pImp;
}

//--------------------------------------------------------------------

void SfxObjectShell::Stamp_SetPrintCancelState(sal_Bool bState)
{
    pImp->bIsPrintJobCancelable = bState;
}

//--------------------------------------------------------------------

sal_Bool SfxObjectShell::Stamp_GetPrintCancelState() const
{
    return pImp->bIsPrintJobCancelable;
}

//--------------------------------------------------------------------

void SfxObjectShell::ViewAssigned()

/*	[Beschreibung]

	Diese Methode wird gerufen, wenn eine View zugewiesen wird.
*/

{
}

//--------------------------------------------------------------------
// closes the Object and all its views

sal_Bool SfxObjectShell::Close()
{
	{DBG_CHKTHIS(SfxObjectShell, 0);}
    SfxObjectShellRef aRef(this);
	if ( !pImp->bClosing )
	{
		// falls noch ein Progress l"auft, nicht schlie\sen
		if ( !pImp->bDisposing && GetProgress() )
			return sal_False;

		pImp->bClosing = sal_True;
		Reference< util::XCloseable > xCloseable( GetBaseModel(), UNO_QUERY );

		if ( xCloseable.is() )
		{
			try
			{
				xCloseable->close( sal_True );
			}
			catch( Exception& )
			{
				pImp->bClosing = sal_False;
			}
		}

		if ( pImp->bClosing )
		{
			// aus Document-Liste austragen
			SfxApplication *pSfxApp = SFX_APP();
			SfxObjectShellArr_Impl &rDocs = pSfxApp->GetObjectShells_Impl();
			const SfxObjectShell *pThis = this;
			sal_uInt16 nPos = rDocs.GetPos(pThis);
			if ( nPos < rDocs.Count() )
				rDocs.Remove( nPos );
			pImp->bInList = sal_False;
		}
	}

	return sal_True;
}

//--------------------------------------------------------------------

// returns a pointer the first SfxDocument of specified type

SfxObjectShell* SfxObjectShell::GetFirst
(
	ConvertToObjectShell    aConvert,
	sal_Bool 			bOnlyVisible
)
{
	SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();

	// search for a SfxDocument of the specified type
	for ( sal_uInt16 nPos = 0; nPos < rDocs.Count(); ++nPos )
	{
		SfxObjectShell* pSh = rDocs.GetObject( nPos );
		if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
			continue;

		if ( ( !aConvert || aConvert(pSh) ) &&
			 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
			return pSh;
	}

	return 0;
}
//--------------------------------------------------------------------

// returns a pointer to the next SfxDocument of specified type behind *pDoc

SfxObjectShell* SfxObjectShell::GetNext
(
	const SfxObjectShell& 	rPrev,
	ConvertToObjectShell    aConvert,
	sal_Bool 					bOnlyVisible
)
{
	SfxObjectShellArr_Impl &rDocs = SFX_APP()->GetObjectShells_Impl();

	// refind the specified predecessor
	sal_uInt16 nPos;
	for ( nPos = 0; nPos < rDocs.Count(); ++nPos )
		if ( rDocs.GetObject(nPos) == &rPrev )
			break;

	// search for the next SfxDocument of the specified type
	for ( ++nPos; nPos < rDocs.Count(); ++nPos )
	{
		SfxObjectShell* pSh = rDocs.GetObject( nPos );
		if ( bOnlyVisible && pSh->IsPreview() && pSh->IsReadOnly() )
			continue;

		if ( ( !aConvert || aConvert(pSh) ) &&
			 ( !bOnlyVisible || SfxViewFrame::GetFirst( pSh, sal_True )))
			return pSh;
	}
	return 0;
}

//--------------------------------------------------------------------

SfxObjectShell* SfxObjectShell::Current()
{
    SfxViewFrame *pFrame = SfxViewFrame::Current();
	return pFrame ? pFrame->GetObjectShell() : 0;
}

//-------------------------------------------------------------------------

sal_Bool SfxObjectShell::IsInPrepareClose() const
{
    return pImp->bInPrepareClose;
}

//------------------------------------------------------------------------

struct BoolEnv_Impl
{
	SfxObjectShell_Impl* pImp;
	BoolEnv_Impl( SfxObjectShell_Impl* pImpP) : pImp( pImpP )
	{ pImpP->bInPrepareClose = sal_True; }
	~BoolEnv_Impl() { pImp->bInPrepareClose = sal_False; }
};


sal_uInt16 SfxObjectShell::PrepareClose
(
	sal_Bool	bUI,		// sal_True: Dialoge etc. erlaubt, sal_False: silent-mode
	sal_Bool	bForBrowsing
)
{
	if( pImp->bInPrepareClose || pImp->bPreparedForClose )
		return sal_True;
	BoolEnv_Impl aBoolEnv( pImp );

	// DocModalDialog?
	if ( IsInModalMode() )
		return sal_False;

	SfxViewFrame* pFirst = SfxViewFrame::GetFirst( this );
	if( pFirst && !pFirst->GetFrame().PrepareClose_Impl( bUI, bForBrowsing ) )
		return sal_False;

	// prepare views for closing
	for ( SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
		  pFrm; pFrm = SfxViewFrame::GetNext( *pFrm, this ) )
	{
		DBG_ASSERT(pFrm->GetViewShell(),"KeineShell");
		if ( pFrm->GetViewShell() )
		{
			sal_uInt16 nRet = pFrm->GetViewShell()->PrepareClose( bUI, bForBrowsing );
			if ( nRet != sal_True )
				return nRet;
		}
	}

    SfxApplication *pSfxApp = SFX_APP();
    pSfxApp->NotifyEvent( SfxEventHint(SFX_EVENT_PREPARECLOSEDOC, GlobalEventConfig::GetEventName(STR_EVENT_PREPARECLOSEDOC), this) );

    if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
	{
		pImp->bPreparedForClose = sal_True;
		return sal_True;
	}

	// ggf. nachfragen, ob gespeichert werden soll
		// nur fuer in sichtbaren Fenstern dargestellte Dokumente fragen
	SfxViewFrame *pFrame = SfxObjectShell::Current() == this
		? SfxViewFrame::Current() : SfxViewFrame::GetFirst( this );

	sal_Bool bClose = sal_False;
	if ( bUI && IsModified() && pFrame )
	{
		// minimierte restoren
        SfxFrame& rTop = pFrame->GetTopFrame();
        SfxViewFrame::SetViewFrame( rTop.GetCurrentViewFrame() );
        pFrame->GetFrame().Appear();

		// fragen, ob gespeichert werden soll
		short nRet = RET_YES;
        //TODO/CLEANUP
        //brauchen wir UI=2 noch?
        //if( SfxApplication::IsPlugin() == sal_False || bUI == 2 )
		{
            //initiate help agent to inform about "print modifies the document"
            SvtPrintWarningOptions aPrintOptions;
            if (aPrintOptions.IsModifyDocumentOnPrintingAllowed() &&
                HasName() && getDocProperties()->getPrintDate().Month > 0)
            {
                SfxHelp::OpenHelpAgent( &pFirst->GetFrame(), HID_CLOSE_WARNING );
            }
            const Reference< XTitle > xTitle( *pImp->pBaseModel.get(), UNO_QUERY_THROW );
            const ::rtl::OUString     sTitle = xTitle->getTitle ();
			nRet = ExecuteQuerySaveDocument(&pFrame->GetWindow(),sTitle);
		}
		/*HACK for plugin::destroy()*/

		if ( RET_YES == nRet )
		{
			// per Dispatcher speichern
			const SfxPoolItem *pPoolItem;
			if ( IsSaveVersionOnClose() )
			{
                SfxStringItem aItem( SID_DOCINFO_COMMENTS, String( SfxResId( STR_AUTOMATICVERSION ) ) );
                SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
                const SfxPoolItem* ppArgs[] = { &aItem, &aWarnItem, 0 };
                pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
			}
			else
            {
                SfxBoolItem aWarnItem( SID_FAIL_ON_WARNING, bUI );
                const SfxPoolItem* ppArgs[] = { &aWarnItem, 0 };
                pPoolItem = pFrame->GetBindings().ExecuteSynchron( SID_SAVEDOC, ppArgs );
            }

            if ( !pPoolItem || dynamic_cast< const SfxVoidItem* >(pPoolItem) || ( dynamic_cast< const SfxBoolItem* >(pPoolItem) && !( (const SfxBoolItem*) pPoolItem )->GetValue() ) )
				return sal_False;
			else
				bClose = sal_True;
		}
		else if ( RET_CANCEL == nRet )
			// abgebrochen
			return sal_False;
		else if ( RET_NEWTASK == nRet )
		{
			return RET_NEWTASK;
		}
		else
		{
			// Bei Nein nicht noch Informationlost
			bClose = sal_True;
		}
	}

	pImp->bPreparedForClose = sal_True;
	return sal_True;
}

//--------------------------------------------------------------------
namespace
{
    static BasicManager* lcl_getBasicManagerForDocument( const SfxObjectShell& _rDocument )
    {
        if ( !_rDocument.Get_Impl()->m_bNoBasicCapabilities )
        {
            if ( !_rDocument.Get_Impl()->bBasicInitialized )
                const_cast< SfxObjectShell& >( _rDocument ).InitBasicManager_Impl();
            return _rDocument.Get_Impl()->pBasicManager->get();
        }

        // assume we do not have Basic ourself, but we can refer to another
        // document which does (by our model's XScriptInvocationContext::getScriptContainer).
        // In this case, we return the BasicManager of this other document.

        OSL_ENSURE( !Reference< XEmbeddedScripts >( _rDocument.GetModel(), UNO_QUERY ).is(),
            "lcl_getBasicManagerForDocument: inconsistency: no Basic, but an XEmbeddedScripts?" );
        Reference< XModel > xForeignDocument;
        Reference< XScriptInvocationContext > xContext( _rDocument.GetModel(), UNO_QUERY );
        if ( xContext.is() )
        {
            xForeignDocument.set( xContext->getScriptContainer(), UNO_QUERY );
            OSL_ENSURE( xForeignDocument.is() && xForeignDocument != _rDocument.GetModel(),
                "lcl_getBasicManagerForDocument: no Basic, but providing ourself as script container?" );
        }

        BasicManager* pBasMgr = NULL;
        if ( xForeignDocument.is() )
            pBasMgr = ::basic::BasicManagerRepository::getDocumentBasicManager( xForeignDocument );

        return pBasMgr;
    }
}

//--------------------------------------------------------------------

BasicManager* SfxObjectShell::GetBasicManager() const
{
    BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
    if ( !pBasMgr )
        pBasMgr = SFX_APP()->GetBasicManager();
    return pBasMgr;
}

//--------------------------------------------------------------------

void SfxObjectShell::SetHasNoBasic()
{
    pImp->m_bNoBasicCapabilities = sal_True;
}

//--------------------------------------------------------------------

sal_Bool SfxObjectShell::HasBasic() const
{
    if ( pImp->m_bNoBasicCapabilities )
        return sal_False;

    if ( !pImp->bBasicInitialized )
        const_cast< SfxObjectShell* >( this )->InitBasicManager_Impl();

    return pImp->pBasicManager->isValid();
}

//--------------------------------------------------------------------
namespace
{
    const Reference< XLibraryContainer >&
    lcl_getOrCreateLibraryContainer( bool _bScript, Reference< XLibraryContainer >& _rxContainer,
        const Reference< XModel >& _rxDocument )
    {
        if ( !_rxContainer.is() )
        {
            try
            {
                Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY );
                const Reference< XComponentContext > xContext(
                    ::comphelper::getProcessComponentContext() );
                _rxContainer.set (   _bScript
                                ?   DocumentScriptLibraryContainer::create(
                                        xContext, xStorageDoc )
                                :   DocumentDialogLibraryContainer::create(
                                        xContext, xStorageDoc )
                                ,   UNO_QUERY_THROW );
            }
            catch( const Exception& )
            {
        	    DBG_UNHANDLED_EXCEPTION();
            }
        }
        return _rxContainer;
    }
}

//--------------------------------------------------------------------

Reference< XLibraryContainer > SfxObjectShell::GetDialogContainer()
{
    if ( !pImp->m_bNoBasicCapabilities )
        return lcl_getOrCreateLibraryContainer( false, pImp->xDialogLibraries, GetModel() );

    BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
    if ( pBasMgr )
        return pBasMgr->GetDialogLibraryContainer().get();

    OSL_ENSURE( false, "SfxObjectShell::GetDialogContainer: falling back to the application - is this really expected here?" );
    return SFX_APP()->GetDialogContainer();
}

//--------------------------------------------------------------------

Reference< XLibraryContainer > SfxObjectShell::GetBasicContainer()
{
    if ( !pImp->m_bNoBasicCapabilities )
        return lcl_getOrCreateLibraryContainer( true, pImp->xBasicLibraries, GetModel() );

    BasicManager* pBasMgr = lcl_getBasicManagerForDocument( *this );
    if ( pBasMgr )
        return pBasMgr->GetScriptLibraryContainer().get();

    OSL_ENSURE( false, "SfxObjectShell::GetBasicContainer: falling back to the application - is this really expected here?" );
    return SFX_APP()->GetBasicContainer();
}

//--------------------------------------------------------------------

StarBASIC* SfxObjectShell::GetBasic() const
{
	return GetBasicManager()->GetLib(0);
}

//--------------------------------------------------------------------

void SfxObjectShell::InitBasicManager_Impl()
/*	[Beschreibung]

    creates a document's BasicManager and loads it, if we are already based on
    a storage.

	[Anmerkung]

	Diese Methode mu"s aus den "Uberladungen von <SvPersist::Load()> (mit
	dem pStor aus dem Parameter von Load()) sowie aus der "Uberladung
	von <SvPersist::InitNew()> (mit pStor = 0) gerufen werden.
*/

{
    /*  #163556# (DR) - Handling of recursive calls while creating the Bacic
        manager.

        It is possible that (while creating the Basic manager) the code that
        imports the Basic storage wants to access the Basic manager again.
        Especially in VBA compatibility mode, there is code that wants to
        access the "VBA Globals" object which is stored as global UNO constant
        in the Basic manager.

        To achieve correct handling of the recursive calls of this function
        from lcl_getBasicManagerForDocument(), the implementation of the
        function BasicManagerRepository::getDocumentBasicManager() has been
        changed to return the Basic manager currently under construction, when
        called repeatedly.
        
        The variable pImp->bBasicInitialized will be set to sal_True after
        construction now, to ensure that the recursive call of the function
        lcl_getBasicManagerForDocument() will be routed into this function too.
        
        Calling BasicManagerHolder::reset() twice is not a big problem, as it
        does not take ownership but stores only the raw pointer. Owner of all
        Basic managers is the global BasicManagerRepository instance.
     */
    DBG_ASSERT( !pImp->bBasicInitialized && !pImp->pBasicManager->isValid(), "Lokaler BasicManager bereits vorhanden");
    pImp->pBasicManager->reset( BasicManagerRepository::getDocumentBasicManager( GetModel() ) );
    DBG_ASSERT( pImp->pBasicManager->isValid(), "SfxObjectShell::InitBasicManager_Impl: did not get a BasicManager!" );
    pImp->bBasicInitialized = sal_True;
}

//--------------------------------------------------------------------

sal_uInt16 SfxObjectShell::Count()
{
	return SFX_APP()->GetObjectShells_Impl().Count();
}

//--------------------------------------------------------------------

sal_Bool SfxObjectShell::DoClose()
{
	return Close();
}

//--------------------------------------------------------------------

SfxObjectShell* SfxObjectShell::GetObjectShell()
{
	return this;
}

//--------------------------------------------------------------------

uno::Sequence< ::rtl::OUString > SfxObjectShell::GetEventNames()
{
	static uno::Sequence< ::rtl::OUString >* pEventNameContainer = NULL;

	if ( !pEventNameContainer )
	{
    	::vos::OGuard aGuard( Application::GetSolarMutex() );
		if ( !pEventNameContainer )
		{
			static uno::Sequence< ::rtl::OUString > aEventNameContainer = GlobalEventConfig().getElementNames();
			pEventNameContainer = &aEventNameContainer;
		}
	}

	return *pEventNameContainer;
}

//--------------------------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetModel() const
{
    return GetBaseModel();
}

void SfxObjectShell::SetBaseModel( SfxBaseModel* pModel )
{
	OSL_ENSURE( !pImp->pBaseModel.is() || pModel == NULL, "Model already set!" );
    pImp->pBaseModel.set( pModel );
    if ( pImp->pBaseModel.is() )
    {
        pImp->pBaseModel->addCloseListener( new SfxModelListener_Impl(this) );
    }
}

//--------------------------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > SfxObjectShell::GetBaseModel() const
{
	return pImp->pBaseModel.get();
}
/* -----------------------------10.09.2001 15:56------------------------------

 ---------------------------------------------------------------------------*/
void SfxObjectShell::SetAutoStyleFilterIndex(sal_uInt16 nSet)
{
    pImp->nStyleFilter = nSet;
}

sal_uInt16 SfxObjectShell::GetAutoStyleFilterIndex()
{
    return pImp->nStyleFilter;
}


void SfxObjectShell::SetCurrentComponent( const Reference< XInterface >& _rxComponent )
{
    Reference< XInterface > xOldCurrentComp(s_xCurrentComponent);
    if ( _rxComponent == xOldCurrentComp )
        // nothing to do
        return;
    // note that "_rxComponent.get() == s_xCurrentComponent.get().get()" is /sufficient/, but not
    // /required/ for "_rxComponent == s_xCurrentComponent.get()".
    // In other words, it's still possible that we here do something which is not necessary,
    // but we should have filtered quite some unnecessary calls already.

    BasicManager* pAppMgr = SFX_APP()->GetBasicManager();
    s_xCurrentComponent = _rxComponent;
    if ( pAppMgr )
    {
        // set "ThisComponent" for Basic
        pAppMgr->SetGlobalUNOConstant( "ThisComponent", Any( _rxComponent ) );

        // set new current component for VBA compatibility
        if ( _rxComponent.is() )
        {
            ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( _rxComponent );
            if ( aVBAConstName.getLength() > 0 )
            {
                pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( _rxComponent ) );
                s_aRegisteredVBAConstants[ _rxComponent.get() ] = aVBAConstName;
            }
        }
        // no new component passed -> remove last registered VBA component
        else if ( xOldCurrentComp.is() )
        {
            ::rtl::OString aVBAConstName = lclGetVBAGlobalConstName( xOldCurrentComp );
            if ( aVBAConstName.getLength() > 0 )
            {
                pAppMgr->SetGlobalUNOConstant( aVBAConstName.getStr(), Any( Reference< XInterface >() ) );
                s_aRegisteredVBAConstants.erase( xOldCurrentComp.get() );
            }
        }
    }
}

Reference< XInterface > SfxObjectShell::GetCurrentComponent()
{
	return s_xCurrentComponent;
}


String SfxObjectShell::GetServiceNameFromFactory( const String& rFact )
{
	//! Remove everything behind name!
	String aFact( rFact );
	String aPrefix = String::CreateFromAscii( "private:factory/" );
	if ( aPrefix.Len() == aFact.Match( aPrefix ) )
		aFact.Erase( 0, aPrefix.Len() );
	sal_uInt16 nPos = aFact.Search( '?' );
	String aParam;
	if ( nPos != STRING_NOTFOUND )
	{
		aParam = aFact.Copy( nPos, aFact.Len() );
		aFact.Erase( nPos, aFact.Len() );
		aParam.Erase(0,1);
	}
	aFact.EraseAllChars('4').ToLowerAscii();

    // HACK: sometimes a real document service name is given here instead of
    // a factory short name. Set return value directly to this service name as fallback
    // in case next lines of code does nothing ...
    // use rFact instead of normed aFact value !
	::rtl::OUString aServiceName = rFact;

	if ( aFact.EqualsAscii("swriter") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
	}
	else if ( aFact.EqualsAscii("sweb") || aFact.EqualsAscii("swriter/web") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
	}
	else if ( aFact.EqualsAscii("sglobal") || aFact.EqualsAscii("swriter/globaldocument") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
	}
	else if ( aFact.EqualsAscii("scalc") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
	}
	else if ( aFact.EqualsAscii("sdraw") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
	}
	else if ( aFact.EqualsAscii("simpress") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
	}
	else if ( aFact.EqualsAscii("schart") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.chart.ChartDocument");
	}
	else if ( aFact.EqualsAscii("smath") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
	}
	else if ( aFact.EqualsAscii("sbasic") )
	{
		aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.script.BasicIDE");
	}
    else if ( aFact.EqualsAscii("sdatabase") )
    {
        aServiceName = ::rtl::OUString::createFromAscii("com.sun.star.sdb.OfficeDatabaseDocument");
    }

	return aServiceName;
}

SfxObjectShell* SfxObjectShell::CreateObjectByFactoryName( const String& rFact, SfxObjectCreateMode eMode )
{
	return CreateObject( GetServiceNameFromFactory( rFact ), eMode );
}


SfxObjectShell* SfxObjectShell::CreateObject( const String& rServiceName, SfxObjectCreateMode eCreateMode )
{
    if ( rServiceName.Len() )
    {
        ::com::sun::star::uno::Reference < ::com::sun::star::frame::XModel > xDoc(
        ::comphelper::getProcessServiceFactory()->createInstance( rServiceName ), UNO_QUERY );
        if ( xDoc.is() )
        {
            ::com::sun::star::uno::Reference < ::com::sun::star::lang::XUnoTunnel > xObj( xDoc, UNO_QUERY );
            ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
            sal_Int64 nHandle = xObj->getSomething( aSeq );
            if ( nHandle )
            {
                SfxObjectShell* pRet = reinterpret_cast< SfxObjectShell* >( sal::static_int_cast< sal_IntPtr >( nHandle ));
                pRet->SetCreateMode_Impl( eCreateMode );
                return pRet;
            }
        }
    }

    return 0;
}

SfxObjectShell* SfxObjectShell::CreateAndLoadObject( const SfxItemSet& rSet, SfxFrame* pFrame )
{
    uno::Sequence < beans::PropertyValue > aProps;
    TransformItems( SID_OPENDOC, rSet, aProps );
    SFX_ITEMSET_ARG(&rSet, pFileNameItem, SfxStringItem, SID_FILE_NAME );
    SFX_ITEMSET_ARG(&rSet, pTargetItem, SfxStringItem, SID_TARGETNAME );
    ::rtl::OUString aURL;
    ::rtl::OUString aTarget = rtl::OUString::createFromAscii("_blank");
    if ( pFileNameItem )
        aURL = pFileNameItem->GetValue();
    if ( pTargetItem )
        aTarget = pTargetItem->GetValue();

    uno::Reference < frame::XComponentLoader > xLoader;
    if ( pFrame )
    {
        xLoader = uno::Reference < frame::XComponentLoader >( pFrame->GetFrameInterface(), uno::UNO_QUERY );
    }
    else
        xLoader = uno::Reference < frame::XComponentLoader >( comphelper::getProcessServiceFactory()->createInstance(
            ::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop") ), uno::UNO_QUERY );

    uno::Reference < lang::XUnoTunnel > xObj;
	try
	{
		xObj = uno::Reference< lang::XUnoTunnel >( xLoader->loadComponentFromURL( aURL, aTarget, 0, aProps ), uno::UNO_QUERY );
	}
	catch( uno::Exception& )
	{}

    if ( xObj.is() )
    {
        ::com::sun::star::uno::Sequence < sal_Int8 > aSeq( SvGlobalName( SFX_GLOBAL_CLASSID ).GetByteSequence() );
        sal_Int64 nHandle = xObj->getSomething( aSeq );
        if ( nHandle )
            return reinterpret_cast< SfxObjectShell* >(sal::static_int_cast< sal_IntPtr >(  nHandle ));
    }

    return NULL;
}

void SfxObjectShell::SetInitialized_Impl( const bool i_fromInitNew )
{
	pImp->bInitialized = sal_True;
    if ( i_fromInitNew )
    {
        SetActivateEvent_Impl( SFX_EVENT_CREATEDOC );
        SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_DOCCREATED, GlobalEventConfig::GetEventName(STR_EVENT_DOCCREATED), this ) );
    }
    else
    {
		SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_LOADFINISHED, GlobalEventConfig::GetEventName(STR_EVENT_LOADFINISHED), this ) );
    }
}


bool SfxObjectShell::IsChangeRecording() const
{
    // currently this function needs to be overwritten by Writer and Calc only
    DBG_ASSERT( 0, "function not implemented" );
    return false;
}

    
bool SfxObjectShell::HasChangeRecordProtection() const
{
    // currently this function needs to be overwritten by Writer and Calc only
    DBG_ASSERT( 0, "function not implemented" );
    return false;
}

    
void SfxObjectShell::SetChangeRecording( bool /*bActivate*/ )
{
    // currently this function needs to be overwritten by Writer and Calc only
    DBG_ASSERT( 0, "function not implemented" );
}

    
bool SfxObjectShell::SetProtectionPassword( const String & /*rPassword*/ )
{
    // currently this function needs to be overwritten by Writer and Calc only
    DBG_ASSERT( 0, "function not implemented" );
    return false;
}    


bool SfxObjectShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > & /*rPasswordHash*/ )
{
    // currently this function needs to be overwritten by Writer and Calc only
    DBG_ASSERT( 0, "function not implemented" );
    return false;
}    

