/**************************************************************
 *
 * 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"

#ifndef _INETMSG_HXX //autogen
#include <svl/inetmsg.hxx>
#endif
#include <tools/diagnose_ex.h>
#include <svl/eitem.hxx>
#include <svl/stritem.hxx>
#include <svl/intitem.hxx>
#include <svtools/svparser.hxx> // SvKeyValue
#include <vos/mutex.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <com/sun/star/script/XTypeConverter.hpp>
#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
#include <com/sun/star/script/FinishEngineEvent.hpp>
#include <com/sun/star/script/InterruptReason.hpp>
#include <com/sun/star/script/XEngineListener.hpp>
#include <com/sun/star/script/XDebugging.hpp>
#ifndef _COM_SUN_STAR_SCRIPT_XINVOKATION_HPP_
#include <com/sun/star/script/XInvocation.hpp>
#endif
#include <com/sun/star/script/ContextInformation.hpp>
#include <com/sun/star/script/FinishReason.hpp>
#include <com/sun/star/script/XEngine.hpp>
#include <com/sun/star/script/InterruptEngineEvent.hpp>
#include <com/sun/star/script/XLibraryAccess.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/XScriptInvocationContext.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/embed/XEmbedPersist.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>


#include <com/sun/star/script/provider/XScript.hpp>
#include <com/sun/star/script/provider/XScriptProvider.hpp>
#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Any.h>
#include <com/sun/star/ucb/XContent.hpp>
#include <com/sun/star/task/ErrorCodeRequest.hpp>
#include <unotools/securityoptions.hxx>

#include "com/sun/star/uri/XUriReferenceFactory.hpp"
#include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>

#include <comphelper/processfactory.hxx>
#include <comphelper/componentcontext.hxx>
#include <comphelper/configurationhelper.hxx>

#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
#include <com/sun/star/task/InteractionClassification.hpp>
#include <com/sun/star/frame/XModel.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::document;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::script::provider;
using namespace ::com::sun::star::container;
#include <basic/sbuno.hxx>
#include <basic/sbstar.hxx>
#ifndef _SB_BASMGR_HXX
#include <basic/basmgr.hxx>
#endif
#ifndef _VCL_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#include <basic/sbx.hxx>
#include <svtools/sfxecode.hxx>
#include <svtools/ehdl.hxx>

#include <unotools/pathoptions.hxx>
#include <unotools/ucbhelper.hxx>
#include <tools/inetmime.hxx>
#include <tools/urlobj.hxx>
#include <svl/inettype.hxx>
#include <svl/sharecontrolfile.hxx>
#include <osl/file.hxx>
#include <rtl/bootstrap.hxx>
#include <vcl/svapp.hxx>
#include <framework/interaction.hxx>
#include <framework/documentundoguard.hxx>
#include <comphelper/interaction.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/documentconstants.hxx>

#include <sfx2/signaturestate.hxx>
#include <sfx2/app.hxx>
#include "appdata.hxx"
#include <sfx2/request.hxx>
#include <sfx2/bindings.hxx>
#include "sfx2/sfxresid.hxx"
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/objsh.hxx>
#include "objshimp.hxx"
#include <sfx2/event.hxx>
#include "fltfnc.hxx"
#include <sfx2/sfx.hrc>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/ctrlitem.hxx>
#include "arrdecl.hxx"
#include <sfx2/module.hxx>
#include <sfx2/docfac.hxx>
#include "helper.hxx"
#include "doc.hrc"
#include "workwin.hxx"
#include "helpid.hrc"
#include "../appl/app.hrc"
#include <sfx2/sfxdlg.hxx>
#include "appbaslib.hxx"
#include <openflag.hxx> // SFX_STREAM_READWRITE

#define C2S(cChar) String::CreateFromAscii( cChar )

using namespace ::com::sun::star;

// class SfxHeaderAttributes_Impl ----------------------------------------

class SfxHeaderAttributes_Impl : public SvKeyValueIterator
{
private:
	SfxObjectShell* pDoc;
	SvKeyValueIteratorRef xIter;
	sal_Bool bAlert;

public:
	SfxHeaderAttributes_Impl( SfxObjectShell* pSh ) :
		SvKeyValueIterator(), pDoc( pSh ),
		xIter( pSh->GetMedium()->GetHeaderAttributes_Impl() ),
		bAlert( sal_False ) {}

	virtual sal_Bool GetFirst( SvKeyValue& rKV ) { return xIter->GetFirst( rKV ); }
	virtual sal_Bool GetNext( SvKeyValue& rKV ) { return xIter->GetNext( rKV ); }
	virtual void Append( const SvKeyValue& rKV );

	void ClearForSourceView() { xIter = new SvKeyValueIterator; bAlert = sal_False; }
	void SetAttributes();
	void SetAttribute( const SvKeyValue& rKV );
};

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

sal_uInt16 __READONLY_DATA aTitleMap_Impl[3][2] =
{
								//	local				remote
	/*	SFX_TITLE_CAPTION	*/	{ 	SFX_TITLE_FILENAME, SFX_TITLE_TITLE },
	/*	SFX_TITLE_PICKLIST	*/	{ 	32,					SFX_TITLE_FULLNAME },
	/*	SFX_TITLE_HISTORY	*/	{ 	32,					SFX_TITLE_FULLNAME }
};

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

void SfxObjectShell::AbortImport()
{
	pImp->bIsAbortingImport = sal_True;
}

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

sal_Bool SfxObjectShell::IsAbortingImport() const
{
	return pImp->bIsAbortingImport;
}

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

uno::Reference<document::XDocumentProperties>
SfxObjectShell::getDocProperties()
{
    uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
        GetModel(), uno::UNO_QUERY_THROW);
    uno::Reference<document::XDocumentProperties> xDocProps(
        xDPS->getDocumentProperties());
    DBG_ASSERT(xDocProps.is(),
        "SfxObjectShell: model has no DocumentProperties");
    return xDocProps;
}

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

void SfxObjectShell::DoFlushDocInfo()
{
}

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

// Note: the only thing that calls this is the modification event handler
// that is installed at the XDocumentProperties
void SfxObjectShell::FlushDocInfo()
{
    if ( IsLoading() )
        return;

	SetModified(sal_True);
    uno::Reference<document::XDocumentProperties> xDocProps(getDocProperties());
    DoFlushDocInfo(); // call template method
    ::rtl::OUString url(xDocProps->getAutoloadURL());
    sal_Int32 delay(xDocProps->getAutoloadSecs());
    SetAutoLoad( INetURLObject(url), delay * 1000,
                 (delay > 0) || url.getLength() );
/*
	// bitte beachten:
	// 1. Titel in DocInfo aber nicht am Doc (nach HTML-Import)
	// 	=> auch am Doc setzen
	// 2. Titel in DocInfo leer (Briefumschlagsdruck)
	//	=> nicht am Doc setzen, da sonst "unbenanntX" daraus wird
	String aDocInfoTitle = GetDocInfo().GetTitle();
	if ( aDocInfoTitle.Len() )
		SetTitle( aDocInfoTitle );
	else
	{
		pImp->aTitle.Erase();
		SetNamedVisibility_Impl();
    	if ( GetMedium() )
    	{
        	SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
        	Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
    	}
    }*/
}

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

void SfxObjectShell::SetError( sal_uInt32 lErr, const ::rtl::OUString& aLogMessage )
{
	if(pImp->lErr==ERRCODE_NONE)
    {
		pImp->lErr=lErr;

        if( lErr != ERRCODE_NONE && aLogMessage.getLength() )
            AddLog( aLogMessage );
    }
}

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

sal_uInt32 SfxObjectShell::GetError() const
{
	return ERRCODE_TOERROR(GetErrorCode());
}

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

sal_uInt32 SfxObjectShell::GetErrorCode() const
{
	sal_uInt32 lError=pImp->lErr;
	if(!lError && GetMedium())
		lError=GetMedium()->GetErrorCode();
	return lError;
}

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

void SfxObjectShell::ResetError()
{
    if( pImp->lErr != ERRCODE_NONE )
        AddLog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX "Resetting Error." ) ) );

	pImp->lErr=0;
	SfxMedium * pMed = GetMedium();
	if( pMed )
		pMed->ResetError();
}

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

sal_Bool SfxObjectShell::IsTemplate() const
{
	return pImp->bIsTemplate;
}

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

void SfxObjectShell::SetTemplate(sal_Bool bIs)
{
	pImp->bIsTemplate=bIs;
	SfxFilterMatcher aMatcher( GetFactory().GetFactoryName() );
	SfxFilterMatcherIter aIter( &aMatcher, SFX_FILTER_TEMPLATEPATH );
	SfxMedium* pMed = GetMedium();
	if( pMed ) pMed->SetFilter( aIter.First() );
}

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

void SfxObjectShell::EnableSetModified( sal_Bool bEnable )
{
#ifdef DBG_UTIL
	if ( bEnable == pImp->m_bEnableSetModified )
		DBG_WARNING( "SFX_PERSIST: EnableSetModified called twice with the same value" );
#endif
	pImp->m_bEnableSetModified = bEnable;
}

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

sal_Bool SfxObjectShell::IsEnableSetModified() const
{
    return pImp->m_bEnableSetModified && !IsReadOnly();
}

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

sal_Bool SfxObjectShell::IsModified()
{
    if ( pImp->m_bIsModified )
        return sal_True;

    if ( !pImp->m_xDocStorage.is() || IsReadOnly() )
    {
        // if the document still has no storage and is not set to be modified explicitly it is not modified
        // a readonly document is also not modified

        return sal_False;
    }

    uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
    for ( sal_Int32 n=0; n<aNames.getLength(); n++ )
    {
        uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aNames[n] );
        OSL_ENSURE( xObj.is(), "An empty entry in the embedded objects list!\n" );
        if ( xObj.is() )
        {
            try
            {
                sal_Int32 nState = xObj->getCurrentState();
                if ( nState != embed::EmbedStates::LOADED )
                {
                    uno::Reference< util::XModifiable > xModifiable( xObj->getComponent(), uno::UNO_QUERY );
                    if ( xModifiable.is() && xModifiable->isModified() )
                        return sal_True;
                }
            }
            catch( uno::Exception& )
            {}
        }
    }

    return sal_False;
}

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

void SfxObjectShell::SetModified( sal_Bool bModifiedP )
{
#ifdef DBG_UTIL
	if ( !bModifiedP && !IsEnableSetModified() )
		DBG_WARNING( "SFX_PERSIST: SetModified( sal_False ), although IsEnableSetModified() == sal_False" );
#endif

	if( !IsEnableSetModified() )
		return;

	if( pImp->m_bIsModified != bModifiedP )
	{
		pImp->m_bIsModified = bModifiedP;
		ModifyChanged();
	}
}

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

void SfxObjectShell::ModifyChanged()
{
	if ( pImp->bClosing )
		// SetModified aus dem dispose des Models!
		return;

	{DBG_CHKTHIS(SfxObjectShell, 0);}

    SfxViewFrame* pViewFrame = SfxViewFrame::Current();
    if ( pViewFrame )
        pViewFrame->GetBindings().Invalidate( SID_SAVEDOCS );

    Invalidate( SID_SIGNATURE );
    Invalidate( SID_MACRO_SIGNATURE );
	Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) );	// xmlsec05, signed state might change in title...

    SFX_APP()->NotifyEvent( SfxEventHint( SFX_EVENT_MODIFYCHANGED, GlobalEventConfig::GetEventName(STR_EVENT_MODIFYCHANGED), this ) );
}

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

sal_Bool SfxObjectShell::IsReadOnlyUI() const

/* 	[Beschreibung]

	Liefert sal_True, wenn das Dokument fuer die UI wie r/o behandelt werden
	soll. Dieses ist unabhaengig vom tatsaechlichen r/o, welches per
	<IsReadOnly()> erfragbar ist.
*/

{
	return pImp->bReadOnlyUI;
}

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

sal_Bool SfxObjectShell::IsReadOnlyMedium() const

/* 	[Beschreibung]

	Liefert sal_True, wenn das Medium r/o ist bzw. r/o geoeffnet wurde.
*/

{
	if ( !pMedium )
		return sal_True;
	return pMedium->IsReadOnly();
}

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

void SfxObjectShell::SetReadOnlyUI( sal_Bool bReadOnly )

/* 	[Beschreibung]

	Schaltet das Dokument in einen r/o bzw. r/w Zustand ohne es neu
	zu laden und ohne die Open-Modi des Mediums zu aendern.
*/

{
	sal_Bool bWasRO = IsReadOnly();
	pImp->bReadOnlyUI = bReadOnly;
	if ( bWasRO != IsReadOnly() )
	{
		Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
		//if ( pImp->pDocInfo )
		//	pImp->pDocInfo->SetReadOnly( IsReadOnly() );
	}
}

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

void SfxObjectShell::SetReadOnly()
{
	// Let the document be completely readonly, means that the
	// medium open mode is adjusted accordingly, and the write lock
	// on the file is removed.

 	if ( pMedium && !IsReadOnlyMedium() )
    {
        sal_Bool bWasROUI = IsReadOnly();

		pMedium->UnlockFile( sal_False );

        // the storage-based mediums are already based on the temporary file
        // so UnlockFile has already closed the locking stream
        if ( !pMedium->HasStorage_Impl() && IsLoadingFinished() )
            pMedium->CloseInStream();

        pMedium->SetOpenMode( SFX_STREAM_READONLY, pMedium->IsDirect(), sal_True );
        pMedium->GetItemSet()->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );

        if ( !bWasROUI )
            Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );
    }
}
//-------------------------------------------------------------------------

sal_Bool SfxObjectShell::IsReadOnly() const
{
	return pImp->bReadOnlyUI || IsReadOnlyMedium();
}

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

sal_Bool SfxObjectShell::IsInModalMode() const
{
    return pImp->bModalMode || pImp->bRunningMacro;
}

//<!--Added by PengYunQuan for Validity Cell Range Picker
sal_Bool SfxObjectShell::AcceptStateUpdate() const
{
	return !IsInModalMode();
}
//-->Added by PengYunQuan for Validity Cell Range Picker

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

sal_Bool SfxObjectShell::HasModalViews() const
{
	SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
	while( pFrame )
	{
		if ( pFrame->IsInModalMode() )
			return sal_True;

		pFrame = SfxViewFrame::GetNext( *pFrame, this );
	}

	return sal_False;
}

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

void SfxObjectShell::SetMacroMode_Impl( sal_Bool bModal )
{
    if ( !pImp->bRunningMacro != !bModal )
	{
        pImp->bRunningMacro = bModal;
		Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
	}
}

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

void SfxObjectShell::SetModalMode_Impl( sal_Bool bModal )
{
	// nur Broadcasten wenn modifiziert, sonst ggf. Endlosrekursion
	if ( !pImp->bModalMode != !bModal )
	{
		// zentral mitz"ahlen
		sal_uInt16 &rDocModalCount = SFX_APP()->Get_Impl()->nDocModalMode;
		if ( bModal )
			++rDocModalCount;
		else
			--rDocModalCount;

		// umschalten
		pImp->bModalMode = bModal;
		Broadcast( SfxSimpleHint( SFX_HINT_MODECHANGED ) );
	}
}

//--------------------------------------------------------------------
sal_Bool SfxObjectShell::SwitchToShared( sal_Bool bShared, sal_Bool bSave )
{
    sal_Bool bResult = sal_True;

    if ( bShared != IsDocShared() )
    {
        ::rtl::OUString aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );

        if ( !aOrigURL.getLength() && bSave )
        {
            // this is a new document, let it be stored before switching to the shared mode;
            // the storing should be done without shared flag, since it is possible that the
            // target location does not allow to create sharing control file;
            // the shared flag will be set later after creation of sharing control file
            SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );

            if ( pViewFrame )
            {
                // TODO/LATER: currently the application guards against the reentrance problem
				const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
                SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
                bResult = ( pResult && pResult->GetValue() );
                if ( bResult )
                    aOrigURL = GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
            }
        }

        sal_Bool bOldValue = HasSharedXMLFlagSet();
        SetSharedXMLFlag( bShared );

        sal_Bool bRemoveEntryOnError = sal_False;
        if ( bResult && bShared )
        {
            try
            {
                ::svt::ShareControlFile aControlFile( aOrigURL );
                aControlFile.InsertOwnEntry();
                bRemoveEntryOnError = sal_True;
            }
            catch( uno::Exception& )
            {
                bResult = sal_False;
            }
        }

        if ( bResult && bSave )
        {
            SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( this );

            if ( pViewFrame )
            {
                // TODO/LATER: currently the application guards against the reentrance problem
                SetModified( sal_True ); // the modified flag has to be set to let the document be stored with the shared flag
				const SfxPoolItem* pItem = pViewFrame->GetBindings().ExecuteSynchron( HasName() ? SID_SAVEDOC : SID_SAVEASDOC );
                SfxBoolItem* pResult = PTR_CAST( SfxBoolItem, pItem );
                bResult = ( pResult && pResult->GetValue() );
            }
        }

        if ( bResult )
        {
            // TODO/LATER: Is it possible that the following calls fail?
            if ( bShared )
            {
                pImp->m_aSharedFileURL = aOrigURL;
                GetMedium()->SwitchDocumentToTempFile();
            }
            else
            {
                ::rtl::OUString aTempFileURL = pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE );
                GetMedium()->SwitchDocumentToFile( GetSharedFileURL() );
                pImp->m_aSharedFileURL = ::rtl::OUString();

                // now remove the temporary file the document was based on
                ::utl::UCBContentHelper::Kill( aTempFileURL );

                try
                {
                    // aOrigURL can not be used since it contains an old value
                    ::svt::ShareControlFile aControlFile( GetMedium()->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
                    aControlFile.RemoveFile();
                }
                catch( uno::Exception& )
                {
                }
            }
        }
        else
        {
            // the saving has failed!
            if ( bRemoveEntryOnError )
            {
                try
                {
                    ::svt::ShareControlFile aControlFile( aOrigURL );
                    aControlFile.RemoveEntry();
                }
                catch( uno::Exception& )
                {}
            }

            SetSharedXMLFlag( bOldValue );
        }
    }
    else
        bResult = sal_False; // the second switch to the same mode

    if ( bResult )
        SetTitle( String() );

    return bResult;
}

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

void SfxObjectShell::DisconnectFromShared()
{
    if ( IsDocShared() )
    {
        if ( pMedium && pMedium->GetStorage().is() )
        {
            // set medium to noname
            pMedium->SetName( String(), sal_True );
            pMedium->Init_Impl();

            // drop resource
            SetNoName();
            InvalidateName();

            // untitled document must be based on temporary storage
            // the medium should not dispose the storage in this case
            if ( pMedium->GetStorage() == GetStorage() )
                ConnectTmpStorage_Impl( pMedium->GetStorage(), pMedium );

            pMedium->Close();
            FreeSharedFile();

            SfxMedium* pTmpMedium = pMedium;
            ForgetMedium();
            if( !DoSaveCompleted( pTmpMedium ) )
                SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
            else
            {
                // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
                pMedium->CanDisposeStorage_Impl( sal_False );
            }

            pMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
            pMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );

            SetTitle( String() );
        }
    }
}

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

void SfxObjectShell::FreeSharedFile()
{
    if ( pMedium )
        FreeSharedFile( pMedium->GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
}

//--------------------------------------------------------------------
void SfxObjectShell::FreeSharedFile( const ::rtl::OUString& aTempFileURL )
{
    SetSharedXMLFlag( sal_False );

    if ( IsDocShared() && aTempFileURL.getLength()
      && !::utl::UCBContentHelper::EqualURLs( aTempFileURL, GetSharedFileURL() ) )
    {
        if ( pImp->m_bAllowShareControlFileClean )
        {
            try
            {
                ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
                aControlFile.RemoveEntry();
            }
            catch( uno::Exception& )
            {
            }
        }

        // the cleaning is forbidden only once
        pImp->m_bAllowShareControlFileClean = sal_True;

        // now remove the temporary file the document is based currently on
        ::utl::UCBContentHelper::Kill( aTempFileURL );

        pImp->m_aSharedFileURL = ::rtl::OUString();
    }
}

//--------------------------------------------------------------------
void SfxObjectShell::DoNotCleanShareControlFile()
{
    pImp->m_bAllowShareControlFileClean = sal_False;
}

//--------------------------------------------------------------------
void SfxObjectShell::SetSharedXMLFlag( sal_Bool bFlag ) const
{
    pImp->m_bSharedXMLFlag = bFlag;
}

//--------------------------------------------------------------------
sal_Bool SfxObjectShell::HasSharedXMLFlagSet() const
{
    return pImp->m_bSharedXMLFlag;
}

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

sal_Bool SfxObjectShell::IsDocShared() const
{
    return ( pImp->m_aSharedFileURL.getLength() > 0 );
}

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

::rtl::OUString SfxObjectShell::GetSharedFileURL() const
{
    return pImp->m_aSharedFileURL;
}

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

Size SfxObjectShell::GetFirstPageSize()
{
    return GetVisArea(ASPECT_THUMBNAIL).GetSize();
}


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

IndexBitSet& SfxObjectShell::GetNoSet_Impl()
{
	return pImp->aBitSet;
}

//--------------------------------------------------------------------
// changes the title of the document

void SfxObjectShell::SetTitle
(
	const String& rTitle		// der neue Titel des Dokuments
)

/*	[Beschreibung]

	Mit dieser Methode kann der Titel des Dokuments gesetzt werden.
	Dieser entspricht initial dem kompletten Dateinamen. Ein Setzen
	des Titels wirkt jedoch nicht zurück auf den Dateinamen; er wird
	jedoch in den Caption-Bars der MDI-Fenster angezeigt.
*/

{
	DBG_CHKTHIS(SfxObjectShell, 0);

	// nix zu tun?
	if ( ( ( HasName() && pImp->aTitle == rTitle )
		|| ( !HasName() && GetTitle() == rTitle ) )
	  && !IsDocShared() )
		return;

	SfxApplication *pSfxApp = SFX_APP();
#if 0
	// wird 'unbenannt#' als Titel gesetzt
	String aNoName(SfxResId(STR_NONAME));
	if ( rTitle.Match(aNoName) <= aNoName.Len() )
	{
		// er ist es selbst => ignorieren
		pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
		pImp->bIsNamedVisible=0;
	}
#endif

	// ggf. die unbenannt-Nummer freigeben
	if ( pImp->bIsNamedVisible && USHRT_MAX != pImp->nVisualDocumentNumber )
	{
		pSfxApp->ReleaseIndex(pImp->nVisualDocumentNumber);
		pImp->bIsNamedVisible = 0;
	}

	// Title setzen
	pImp->aTitle = rTitle;
//	Wieso denn in der DocInfo?
//	GetDocInfo().SetTitle( rTitle );
//	FlushDocInfo();

	// Benachrichtigungen
    if ( GetMedium() )
    {
        SfxShell::SetName( GetTitle(SFX_TITLE_APINAME) );
        Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
    }
}

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

#if OSL_DEBUG_LEVEL > 1
String X(const String &rRet)
{
	if ( !rRet.Len() )
		return DEFINE_CONST_UNICODE( "-empty-" );
	return rRet;
}
#else
#define X(ret) ret
#endif

//--------------------------------------------------------------------
//--------------------------------------------------------------------
String SfxObjectShell::GetTitle
(
	sal_uInt16	nMaxLength 		/*	0 (default)
								der Titel selbst, so wie er ist

								1 (==SFX_TITLE_FILENAME)
								liefert den logischen Dateinamen ohne Pfad
								(unter WNT je nach Systemeinstellung ohne
								Extension)

								2 (==SFX_TITLE_FULLNAME)
								liefert den mit komplettem logischen Dateinamen
								mit Pfad (remote => ::com::sun::star::util::URL)

								3 (==SFX_TITLE_APINAME)
								liefert den logischen Dateinamen ohne Pfad
								und Extension

								4 (==SFX_TITLE_DETECT)
								liefert den kompletten Titel, falls noch
								nicht gesetzt wird aber aus DocInfo oder
								dem Namen des Medium erzeugt

								5 (==SFX_TITLE_CAPTION)
								liefert den Titel so, wie MB ihn heute in
								der CaptionBar anzeigen m"ochte

								6 (==SFX_TITLE_PICKLIST)
								liefert den Titel so, wie MB ihn heute in
								der PickList anzeigen m"ochte

								7 (==SFX_TITLE_HISTORY)
								liefert den Titel so, wie MB ihn heute in
								der History anzeigen m"ochte

								10 bis USHRT_MAX
								liefert maximal 'nMaxLength' Zeichen vom logischen
								Dateinamen inkl. Pfad (remote => ::com::sun::star::util::URL)
								*/
) const

/*	[Beschreibung]

	Liefert den Titel bzw. logischen Dateinamen des Dokuments, je nach
	'nMaxLength'.

	Falls der Dateiname mit Pfad verwendet wird, wird die Namensk"urzung durch
	Ersetzung eines oder mehrerer Directory-Namen durch "..." durchgef"uhrt,
	URLs werden z.Zt. immer komplett geliefert.
*/

{
//    if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED )
//        return String();
    SfxMedium *pMed = GetMedium();
    if ( IsLoading() )
        return String();

/*    if ( !nMaxLength && pImp->pDocInfo )
    {
        String aTitle = pImp->pDocInfo->GetTitle();
        if ( aTitle.Len() )
            return aTitle;
    } */

	// Titel erzeugen?
	if ( SFX_TITLE_DETECT == nMaxLength && !pImp->aTitle.Len() )
	{
		static sal_Bool bRecur = sal_False;
		if ( bRecur )
			return DEFINE_CONST_UNICODE( "-not available-" );
		bRecur = sal_True;

		String aTitle;
		SfxObjectShell *pThis = (SfxObjectShell*) this;

		if ( pMed )
		{
			SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
			if ( pNameItem )
				aTitle = pNameItem->GetValue();
		}

		if ( !aTitle.Len() )
			aTitle = GetTitle( SFX_TITLE_FILENAME );

		if ( IsTemplate() )
			pThis->SetTitle( aTitle );
		bRecur = sal_False;
		return X(aTitle);
	}
	else if (SFX_TITLE_APINAME == nMaxLength )
		return X(GetAPIName());

	// Sonderfall Vorlagen:
	if( IsTemplate() && pImp->aTitle.Len() &&
		 ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
		return X(pImp->aTitle);

	// Picklist/Caption wird gemappt
	if ( pMed && ( nMaxLength == SFX_TITLE_CAPTION || nMaxLength == SFX_TITLE_PICKLIST ) )
	{
		// Wenn ein spezieller Titel beim Öffnen mitgegeben wurde;
		// wichtig bei URLs, die INET_PROT_FILE verwenden, denn bei denen
		// wird der gesetzte Titel nicht beachtet.
		// (s.u., Auswertung von aTitleMap_Impl)
		SFX_ITEMSET_ARG( pMed->GetItemSet(), pNameItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False );
		if ( pNameItem )
			return X( pNameItem->GetValue() );
	}

	// noch unbenannt?
	DBG_ASSERT( !HasName() || pMed, "HasName() but no Medium?" );
	if ( !HasName() || !pMed )
	{
		// schon Titel gesetzt?
		if ( pImp->aTitle.Len() )
			return X(pImp->aTitle);

		// muß es durchnumeriert werden?
		String aNoName( SfxResId( STR_NONAME ) );
		if ( pImp->bIsNamedVisible ) {
			// Leerzeichen und Nummer hinten anhängen
			aNoName += C2S(" ");
			aNoName += String::CreateFromInt32( pImp->nVisualDocumentNumber );
		}

		// Dokument heißt vorerst 'Unbenannt #'
		return X(aNoName);
	}

	const INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
	if ( nMaxLength > SFX_TITLE_CAPTION && nMaxLength <= SFX_TITLE_HISTORY )
	{
		sal_uInt16 nRemote;
		if( !pMed || aURL.GetProtocol() == INET_PROT_FILE )
			nRemote = 0;
		else
			nRemote = 1;
		nMaxLength = aTitleMap_Impl[nMaxLength-SFX_TITLE_CAPTION][nRemote];
	}

	// local file?
	if ( aURL.GetProtocol() == INET_PROT_FILE )
	{
        String aName( aURL.HasMark() ? INetURLObject( aURL.GetURLNoMark() ).PathToFileName() : aURL.PathToFileName() );
		if ( nMaxLength == SFX_TITLE_FULLNAME )
			return X( aName );
		else if ( nMaxLength == SFX_TITLE_FILENAME )
            return X( aURL.getName( INetURLObject::LAST_SEGMENT,
				true, INetURLObject::DECODE_WITH_CHARSET ) );
		else if ( !pImp->aTitle.Len() )
            pImp->aTitle = aURL.getBase( INetURLObject::LAST_SEGMENT,
										 true, INetURLObject::DECODE_WITH_CHARSET );
	}
	else
	{
		// ::com::sun::star::util::URL-Versionen
		if ( nMaxLength >= SFX_TITLE_MAXLEN )
		{
            String aComplete( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
			if( aComplete.Len() > nMaxLength )
			{
				String aRet( DEFINE_CONST_UNICODE( "..." ) );
				aRet += aComplete.Copy( aComplete.Len() - nMaxLength + 3, nMaxLength - 3 );
				return X( aRet );
			}
			else
                return X( aComplete );
		}
		else if ( nMaxLength == SFX_TITLE_FILENAME )
		{
            String aName( aURL.GetBase() );
			aName = INetURLObject::decode( aName, INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET );
			if( !aName.Len() )
				aName = aURL.GetURLNoPass();
			return X(aName);
		}
		else if ( nMaxLength == SFX_TITLE_FULLNAME )
			return X(aURL.GetMainURL( INetURLObject::DECODE_TO_IURI ));

		// ggf. Titel aus Dateiname generieren
		if ( !pImp->aTitle.Len() )
			pImp->aTitle = aURL.GetBase();

		// workaround for the case when the name can not be retrieved from URL by INetURLObject
		if ( !pImp->aTitle.Len() )
			pImp->aTitle = aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET );
	}

	// ganzer Titel
	return X(pImp->aTitle);
}

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

void SfxObjectShell::InvalidateName()

/*	[Beschreibung]

	Ermittelt den Titel des Dokuments neu aus 'unbenannt', DocInfo-Titel
	bzw. Dateinamen. Wird nach Laden aus Template oder SaveAs benötigt.
*/

{
	// Title neu erzeugen
	pImp->aTitle.Erase();
//	pImp->nVisualDocumentNumber = USHRT_MAX;
	//GetTitle( SFX_TITLE_DETECT );
	SetName( GetTitle( SFX_TITLE_APINAME ) );

	// Benachrichtigungen
	Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
}

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

void SfxObjectShell::SetNamedVisibility_Impl()
{
	if ( !pImp->bIsNamedVisible )
	{
		// Nummer verpassen
		pImp->bIsNamedVisible = sal_True;
		// ggf. neue Nummer verpassen
		if ( !HasName() && USHRT_MAX == pImp->nVisualDocumentNumber && !pImp->aTitle.Len() )
		{
			pImp->nVisualDocumentNumber = SFX_APP()->GetFreeIndex();
			Broadcast( SfxSimpleHint(SFX_HINT_TITLECHANGED) );
		}
	}

	SetName( GetTitle(SFX_TITLE_APINAME) );
}

void SfxObjectShell::SetNoName()
{
    bHasName = 0;
    bIsTmp = sal_True;
    GetModel()->attachResource( ::rtl::OUString(), GetModel()->getArgs() );
}

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

void SfxObjectShell::MemoryError()
{
}

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

SfxProgress* SfxObjectShell::GetProgress() const
{
	return pImp->pProgress;
}

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

void SfxObjectShell::SetProgress_Impl
(
	SfxProgress *pProgress	/*	zu startender <SfxProgress> oder 0, falls
								der Progress zur"uckgesetzt werden soll */
)

/*	[Beschreibung]

	Interne Methode zum setzen oder zur"ucksetzen des Progress-Modes
	f"ur diese SfxObjectShell.
*/

{
	DBG_ASSERT( ( !pImp->pProgress && pProgress ) ||
				( pImp->pProgress && !pProgress ),
				"Progress activation/deactivation mismatch" );
	pImp->pProgress = pProgress;
}

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

void SfxObjectShell::PostActivateEvent_Impl( SfxViewFrame* pFrame )
{
	SfxApplication* pSfxApp = SFX_APP();
    if ( !pSfxApp->IsDowning() && !IsLoading() && pFrame && !pFrame->GetFrame().IsClosing_Impl() )
	{
        SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
        if ( !pHiddenItem || !pHiddenItem->GetValue() )
        {
            sal_uInt16 nId = pImp->nEventId;
            pImp->nEventId = 0;
            if ( nId == SFX_EVENT_OPENDOC )
                pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_OPENDOC), this, pFrame->GetFrame().GetController() ), sal_False);
			else if (nId == SFX_EVENT_CREATEDOC )
                pSfxApp->NotifyEvent(SfxViewEventHint( nId, GlobalEventConfig::GetEventName(STR_EVENT_CREATEDOC), this, pFrame->GetFrame().GetController() ), sal_False);
        }
	}
}

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

void SfxObjectShell::SetActivateEvent_Impl(sal_uInt16 nId )
{
	if ( GetFactory().GetFlags() & SFXOBJECTSHELL_HASOPENDOC )
		pImp->nEventId = nId;
}

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

void SfxObjectShell::RegisterTransfer( SfxMedium& rMedium )
/*  [Beschreibung ]
	Alle Medien, die aufgesetzt werden, um Teile eines Dokumentes zu
	laden, muessen an der zugehoerigen SfxObjectShell angemeldet
	werden. So kann dokumentweise abgebrochen werden.  */
{
	rMedium.SetReferer( GetMedium()->GetName() );
}

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

void SfxObjectShell::PrepareReload( )
/*  [Beschreibung ]
	Wird vor dem Reload gerufen und gibt die Moeglichkeit,
	etwaige Caches zu leeren. */
{
}

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

void SfxObjectShell::LockAutoLoad( sal_Bool bLock )

/* 	Verhindert ein evtl. eintreffendes AutoLoad. Wird auch vor AutoLoad
	eines umgebenden FrameSet beruecksichtigt.
*/

{
	if ( bLock )
		++pImp->nAutoLoadLocks;
	else
		--pImp->nAutoLoadLocks;
}

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

// kann nach frame.cxx gemoved werden, wenn 358+36x-Stand gemerged sind

sal_Bool SfxFrame::IsAutoLoadLocked_Impl() const
{
	// sein einges Doc gelockt?
	const SfxObjectShell* pObjSh = GetCurrentDocument();
	if ( !pObjSh || !pObjSh->IsAutoLoadLocked() )
		return sal_False;

	// seine Childs gelockt?
	for ( sal_uInt16 n = GetChildFrameCount(); n--; )
		if ( !GetChildFrame(n)->IsAutoLoadLocked_Impl() )
			return sal_False;

	// sonst ist AutoLoad erlaubt
	return sal_True;
}

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

sal_Bool SfxObjectShell::IsAutoLoadLocked() const

/* 	Liefert, ob ein eintreffendes AutoLoad ausgefuehrt werden darf. Wird auch
	vor AutoLoad eines umgebenden FrameSet beruecksichtigt.
*/

{
	return !IsReadOnly() || pImp->nAutoLoadLocks > 0;
}

//-------------------------------------------------------------------------
void SfxObjectShell::BreakMacroSign_Impl( sal_Bool bBreakMacroSign )
{
	pImp->m_bMacroSignBroken = bBreakMacroSign;
}

//-------------------------------------------------------------------------
void SfxObjectShell::CheckSecurityOnLoading_Impl()
{
    uno::Reference< task::XInteractionHandler > xInteraction;
    if ( GetMedium() )
        xInteraction = GetMedium()->GetInteractionHandler();

	// check if there is a broken signature...
    CheckForBrokenDocSignatures_Impl( xInteraction );

    CheckEncryption_Impl( xInteraction );

    // check macro security
    pImp->aMacroMode.checkMacrosOnLoading( xInteraction );
}

//-------------------------------------------------------------------------
void SfxObjectShell::CheckEncryption_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
{
    ::rtl::OUString aVersion;
    sal_Bool bIsEncrypted = sal_False;
    sal_Bool bHasNonEncrypted = sal_False;

    try
    {
        uno::Reference < beans::XPropertySet > xPropSet( GetStorage(), uno::UNO_QUERY_THROW );
        xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
        xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasEncryptedEntries" ) ) ) >>= bIsEncrypted;
        xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HasNonEncryptedEntries" ) ) ) >>= bHasNonEncrypted;
    }
    catch( uno::Exception& )
    {
    }

    if ( aVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
    {
        // this is ODF1.2 or later
        if ( bIsEncrypted && bHasNonEncrypted )
        {
            if ( !pImp->m_bIncomplEncrWarnShown )
            {
                // this is an encrypted document with nonencrypted streams inside, show the warning
                ::com::sun::star::task::ErrorCodeRequest aErrorCode;
                aErrorCode.ErrCode = ERRCODE_SFX_INCOMPLETE_ENCRYPTION;

                SfxMedium::CallApproveHandler( xHandler, uno::makeAny( aErrorCode ), sal_False );
                pImp->m_bIncomplEncrWarnShown = sal_True;
            }

            // broken signatures imply no macro execution at all
            pImp->aMacroMode.disallowMacroExecution();
        }
    }
}

//-------------------------------------------------------------------------
void SfxObjectShell::CheckForBrokenDocSignatures_Impl( const uno::Reference< task::XInteractionHandler >& xHandler )
{
    sal_Int16 nSignatureState = GetDocumentSignatureState();
    bool bSignatureBroken = ( nSignatureState == SIGNATURESTATE_SIGNATURES_BROKEN );
    if ( !bSignatureBroken )
        return;

    pImp->showBrokenSignatureWarning( xHandler );

    // broken signatures imply no macro execution at all
    pImp->aMacroMode.disallowMacroExecution();
}

//-------------------------------------------------------------------------
void SfxObjectShell::SetAutoLoad(
	const INetURLObject& rUrl, sal_uInt32 nTime, sal_Bool bReload )
{
	if ( pImp->pReloadTimer )
		DELETEZ(pImp->pReloadTimer);
	if ( bReload )
	{
		pImp->pReloadTimer = new AutoReloadTimer_Impl(
								rUrl.GetMainURL( INetURLObject::DECODE_TO_IURI ),
								nTime, bReload, this );
		pImp->pReloadTimer->Start();
	}
}

sal_Bool SfxObjectShell::IsLoadingFinished() const
{
	return ( pImp->nLoadedFlags == SFX_LOADED_ALL );
}

void impl_addToModelCollection(const com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel);
void SfxObjectShell::InitOwnModel_Impl()
{
	if ( !pImp->bModelInitialized )
	{
		SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
		if ( pSalvageItem )
		{
            pImp->aTempName = pMedium->GetPhysicalName();
			pMedium->GetItemSet()->ClearItem( SID_DOC_SALVAGE );
			pMedium->GetItemSet()->ClearItem( SID_FILE_NAME );
			pMedium->GetItemSet()->Put( SfxStringItem( SID_FILE_NAME, pMedium->GetOrigURL() ) );
		}
		else
		{
			pMedium->GetItemSet()->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
			pMedium->GetItemSet()->ClearItem( SID_DOCUMENT );
		}

		pMedium->GetItemSet()->ClearItem( SID_REFERER );
		uno::Reference< frame::XModel > xModel ( GetModel(), uno::UNO_QUERY );
		if ( xModel.is() )
		{
			::rtl::OUString aURL = GetMedium()->GetOrigURL();
			SfxItemSet *pSet = GetMedium()->GetItemSet();
            if ( !GetMedium()->IsReadOnly() )
                pSet->ClearItem( SID_INPUTSTREAM );
			uno::Sequence< beans::PropertyValue > aArgs;
			TransformItems( SID_OPENDOC, *pSet, aArgs );
			xModel->attachResource( aURL, aArgs );
            impl_addToModelCollection(xModel);
		}

		pImp->bModelInitialized = sal_True;
	}
}

void SfxObjectShell::FinishedLoading( sal_uInt16 nFlags )
{
	sal_Bool bSetModifiedTRUE = sal_False;
	SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
    if( ( nFlags & SFX_LOADED_MAINDOCUMENT ) && !(pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT )
	    && !(pImp->nFlagsInProgress & SFX_LOADED_MAINDOCUMENT ))
	{
		pImp->nFlagsInProgress |= SFX_LOADED_MAINDOCUMENT;
		((SfxHeaderAttributes_Impl*)GetHeaderAttributes())->SetAttributes();
		pImp->bImportDone = sal_True;
		if( !IsAbortingImport() )
			PositionView_Impl();

        if ( ( GetModifyPasswordHash() || GetModifyPasswordInfo().getLength() ) && !IsModifyPasswordEntered() )
            SetReadOnly();

		// Salvage
		if ( pSalvageItem )
			bSetModifiedTRUE = sal_True;

		if ( !IsEnableSetModified() )
			EnableSetModified( sal_True );

		if( !bSetModifiedTRUE && IsEnableSetModified() )
			SetModified( sal_False );

        CheckSecurityOnLoading_Impl();

		bHasName = sal_True; // the document is loaded, so the name should already available
		GetTitle( SFX_TITLE_DETECT );
		InitOwnModel_Impl();
		pImp->nFlagsInProgress &= ~SFX_LOADED_MAINDOCUMENT;
	}

    if( ( nFlags & SFX_LOADED_IMAGES ) && !(pImp->nLoadedFlags & SFX_LOADED_IMAGES )
	    && !(pImp->nFlagsInProgress & SFX_LOADED_IMAGES ))
	{
		pImp->nFlagsInProgress |= SFX_LOADED_IMAGES;
        uno::Reference<document::XDocumentProperties> xDocProps(
            getDocProperties());
        ::rtl::OUString url(xDocProps->getAutoloadURL());
        sal_Int32 delay(xDocProps->getAutoloadSecs());
        SetAutoLoad( INetURLObject(url), delay * 1000,
                     (delay > 0) || url.getLength() );
		if( !bSetModifiedTRUE && IsEnableSetModified() )
			SetModified( sal_False );
		Invalidate( SID_SAVEASDOC );
		pImp->nFlagsInProgress &= ~SFX_LOADED_IMAGES;
	}

	pImp->nLoadedFlags |= nFlags;

	if ( !pImp->nFlagsInProgress )
	{
		// in case of reentrance calls the first called FinishedLoading() call on the stack
		// should do the notification, in result the notification is done when all the FinishedLoading() calls are finished

		if ( bSetModifiedTRUE )
			SetModified( sal_True );
		else
			SetModified( sal_False );

		if ( (pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT ) && (pImp->nLoadedFlags & SFX_LOADED_IMAGES ) )
		{
            SFX_ITEMSET_ARG( pMedium->GetItemSet(), pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False);
            sal_Bool bTemplate = pTemplateItem && pTemplateItem->GetValue();

			// closing the streams on loading should be under control of SFX!
			DBG_ASSERT( pMedium->IsOpen(), "Don't close the medium when loading documents!" );

            if ( bTemplate )
            {
                TemplateDisconnectionAfterLoad();
            }
            else
            {
                // if a readonly medium has storage then it's stream is already based on temporary file
                if( !(pMedium->GetOpenMode() & STREAM_WRITE) && !pMedium->HasStorage_Impl() )
                    // don't lock file opened read only
                    pMedium->CloseInStream();
            }
		}

        SetInitialized_Impl( false );

		// Title is not available until loading has finished
		Broadcast( SfxSimpleHint( SFX_HINT_TITLECHANGED ) );
		if ( pImp->nEventId )
			PostActivateEvent_Impl(SfxViewFrame::GetFirst(this));
	}
}

//-------------------------------------------------------------------------
extern void SetTemplate_Impl( const String&, const String&, SfxObjectShell* );

void SfxObjectShell::TemplateDisconnectionAfterLoad()
{
    // document is created from a template
    //TODO/LATER: should the templates always be XML docs!

    SfxMedium* pTmpMedium = pMedium;
    if ( pTmpMedium )
    {
        String aName( pTmpMedium->GetName() );
        SFX_ITEMSET_ARG( pTmpMedium->GetItemSet(), pTemplNamItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
        String aTemplateName;
        if ( pTemplNamItem )
            aTemplateName = pTemplNamItem->GetValue();
        else
        {
            // !TODO/LATER: what's this?!
            // Interaktiv ( DClick, Contextmenu ) kommt kein Langname mit
            aTemplateName = getDocProperties()->getTitle();
            if ( !aTemplateName.Len() )
            {
                INetURLObject aURL( aName );
                aURL.CutExtension();
                aTemplateName = aURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
            }
        }

        // set medium to noname
        pTmpMedium->SetName( String(), sal_True );
        pTmpMedium->Init_Impl();

        // drop resource
        SetNoName();
        InvalidateName();

        if( IsPackageStorageFormat_Impl( *pTmpMedium ) )
        {
            // untitled document must be based on temporary storage
            // the medium should not dispose the storage in this case
            uno::Reference < embed::XStorage > xTmpStor = ::comphelper::OStorageHelper::GetTemporaryStorage();
            GetStorage()->copyToStorage( xTmpStor );

            // the medium should disconnect from the original location
            // the storage should not be disposed since the document is still
            // based on it, but in DoSaveCompleted it will be disposed
            pTmpMedium->CanDisposeStorage_Impl( sal_False );
            pTmpMedium->Close();

            // setting the new storage the medium will be based on
            pTmpMedium->SetStorage_Impl( xTmpStor );

            ForgetMedium();
            if( !DoSaveCompleted( pTmpMedium ) )
                SetError( ERRCODE_IO_GENERAL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
            else
            {
                SFX_ITEMSET_ARG( pMedium->GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False );
                sal_Bool bSalvage = pSalvageItem ? sal_True : sal_False;

                if ( !bSalvage )
                {
                    // some further initializations for templates
                    SetTemplate_Impl( aName, aTemplateName, this );
                }

                // the medium should not dispose the storage, DoSaveCompleted() has let it to do so
                pTmpMedium->CanDisposeStorage_Impl( sal_False );
            }
        }
        else
        {
            // some further initializations for templates
            SetTemplate_Impl( aName, aTemplateName, this );
            pTmpMedium->CreateTempFile( sal_True );
        }

        // templates are never readonly
        pTmpMedium->GetItemSet()->ClearItem( SID_DOC_READONLY );
        pTmpMedium->SetOpenMode( SFX_STREAM_READWRITE, sal_True, sal_True );

        // notifications about possible changes in readonly state and document info
        Broadcast( SfxSimpleHint(SFX_HINT_MODECHANGED) );

        // created untitled document can't be modified
        SetModified( sal_False );
    }
}

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

void SfxObjectShell::PositionView_Impl()
{
	MarkData_Impl *pMark = Get_Impl()->pMarkData;
	if( pMark )
	{
		SfxViewShell* pSh = pMark->pFrame->GetViewShell();
		if( pMark->aUserData.Len() )
			pSh->ReadUserData( pMark->aUserData, sal_True );
		else if( pMark->aMark.Len() )
			pSh->JumpToMark( pMark->aMark );
		DELETEZ( Get_Impl()->pMarkData );
	}
}

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

sal_Bool SfxObjectShell::IsLoading() const
/*  [Beschreibung ]
	Has FinishedLoading been called? */
{
	return !( pImp->nLoadedFlags & SFX_LOADED_MAINDOCUMENT );
}

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

void SfxObjectShell::CancelTransfers()
/*  [Beschreibung ]
	Hier koennen Transfers gecanceled werden, die nicht mit
	RegisterTransfer registiert wurden */
{
	if( ( pImp->nLoadedFlags & SFX_LOADED_ALL ) != SFX_LOADED_ALL )
	{
		AbortImport();
		if( IsLoading() )
			FinishedLoading( SFX_LOADED_ALL );

/*
		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
		while( pFrame )
		{
			pFrame->CancelTransfers();
			pFrame = SfxViewFrame::GetNext( *pFrame, this );
		}*/
	}
}

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

AutoReloadTimer_Impl::AutoReloadTimer_Impl(
	const String& rURL, sal_uInt32 nTime, sal_Bool bReloadP, SfxObjectShell* pSh )
	: aUrl( rURL ), bReload( bReloadP ), pObjSh( pSh )
{
	SetTimeout( nTime );
}

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

void AutoReloadTimer_Impl::Timeout()
{
	SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjSh );

	if ( pFrame )
	{
		// momentan nicht m"oglich/sinnvoll?
        if ( !pObjSh->CanReload_Impl() || pObjSh->IsAutoLoadLocked() || Application::IsUICaptured() )
		{
			// erneuten Versuch erlauben
			Start();
			return;
		}

		SfxAllItemSet aSet( SFX_APP()->GetPool() );
		aSet.Put( SfxBoolItem( SID_AUTOLOAD, sal_True ) );
		if ( aUrl.Len() )
			aSet.Put(  SfxStringItem( SID_FILE_NAME, aUrl ) );
		SfxRequest aReq( SID_RELOAD, 0, aSet );
		pObjSh->Get_Impl()->pReloadTimer = 0;
		delete this;
		pFrame->ExecReload_Impl( aReq );
		return;
	}

	pObjSh->Get_Impl()->pReloadTimer = 0;
	delete this;
}

SfxModule* SfxObjectShell::GetModule() const
{
	return GetFactory().GetModule();
}

ErrCode SfxObjectShell::CallBasic( const String& rMacro,
	const String& rBasic, SbxArray* pArgs,
	SbxValue* pRet )
{
    SfxApplication* pApp = SFX_APP();
    if( pApp->GetName() != rBasic )
    {
        if ( !AdjustMacroMode( String() ) )
            return ERRCODE_IO_ACCESSDENIED;
    }

    BasicManager *pMgr = GetBasicManager();
    if( pApp->GetName() == rBasic )
        pMgr = pApp->GetBasicManager();
    ErrCode nRet = SfxApplication::CallBasic( rMacro, pMgr, pArgs, pRet );
    return nRet;
}

namespace
{
    static bool lcl_isScriptAccessAllowed_nothrow( const Reference< XInterface >& _rxScriptContext )
    {
        try
        {
            Reference< XEmbeddedScripts > xScripts( _rxScriptContext, UNO_QUERY );
            if ( !xScripts.is() )
            {
                Reference< XScriptInvocationContext > xContext( _rxScriptContext, UNO_QUERY_THROW );
                xScripts.set( xContext->getScriptContainer(), UNO_SET_THROW );
            }

            return xScripts->getAllowMacroExecution();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return false;
    }
}

ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptContext, const ::rtl::OUString& _rScriptURL,
    const Sequence< Any >& aParams, Any& aRet, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam,
    const ::rtl::OUString& aReferer, bool bRaiseError )
{
    OSL_TRACE( "in CallXScript" );
	ErrCode nErr = ERRCODE_NONE;

	bool bCaughtException = false;
    Any aException;
    bool bRefererIsTrusted = ( aReferer.compareToAscii("private:", 8) == 0 );
    try
    {
        uno::Reference< lang::XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
        Reference< uri::XUriReferenceFactory > xFac (
            xServiceManager->createInstance( rtl::OUString::createFromAscii(
                "com.sun.star.uri.UriReferenceFactory") ) , UNO_QUERY_THROW );
        Reference< uri::XVndSunStarScriptUrlReference > xScriptUri( xFac->parse( _rScriptURL ), UNO_QUERY_THROW );
        if ( !bRefererIsTrusted && !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) )
            return ERRCODE_IO_ACCESSDENIED;

        // obtain/create a script provider
        Reference< provider::XScriptProvider > xScriptProvider;
        Reference< provider::XScriptProviderSupplier > xSPS( _rxScriptContext, UNO_QUERY );
        if ( xSPS.is() )
            xScriptProvider.set( xSPS->getScriptProvider() );

        if ( !xScriptProvider.is() )
        {
            ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            Reference< provider::XScriptProviderFactory > xScriptProviderFactory(
                aContext.getSingleton( "com.sun.star.script.provider.theMasterScriptProviderFactory" ), UNO_QUERY_THROW );
            xScriptProvider.set( xScriptProviderFactory->createScriptProvider( makeAny( _rxScriptContext ) ), UNO_SET_THROW );
        }

        // ry to protect the invocation context's undo manager (if present), just in case the script tampers with it
        ::framework::DocumentUndoGuard aUndoGuard( _rxScriptContext.get() );

        // obtain the script, and execute it
        Reference< provider::XScript > xScript( xScriptProvider->getScript( _rScriptURL ), UNO_QUERY_THROW );
        aRet = xScript->invoke( aParams, aOutParamIndex, aOutParam );
    }
    catch ( const uno::Exception& )
    {
        aException = ::cppu::getCaughtException();
		bCaughtException = sal_True;
        nErr = ERRCODE_BASIC_INTERNAL_ERROR;
    }

	if ( bCaughtException && bRaiseError )
	{
        ::std::auto_ptr< VclAbstractDialog > pScriptErrDlg;
		SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
        if ( pFact )
            pScriptErrDlg.reset( pFact->CreateScriptErrorDialog( NULL, aException ) );
        OSL_ENSURE( pScriptErrDlg.get(), "SfxObjectShell::CallXScript: no script error dialog!" );

        if ( pScriptErrDlg.get() )
			pScriptErrDlg->Execute();
	}

    OSL_TRACE( "leaving CallXScript" );
    return nErr;
}

// perhaps rename to CallScript once we get rid of the existing CallScript
// and Call, CallBasic, CallStarBasic methods
ErrCode SfxObjectShell::CallXScript( const String& rScriptURL,
        const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >&
            aParams,
        ::com::sun::star::uno::Any& aRet,
        ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
        ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam,
        const ::rtl::OUString& aReferer,
        bool bRaiseError )
{
    return CallXScript( GetModel(), rScriptURL, aParams, aRet, aOutParamIndex, aOutParam, aReferer, bRaiseError );
}

//-------------------------------------------------------------------------
SfxFrame* SfxObjectShell::GetSmartSelf( SfxFrame* pSelf, SfxMedium& /*rMedium*/ )
{
	return pSelf;
}

SfxObjectShellFlags SfxObjectShell::GetFlags() const
{
	if( pImp->eFlags == SFXOBJECTSHELL_UNDEFINED )
		pImp->eFlags = GetFactory().GetFlags();
	return pImp->eFlags;
}

void SfxObjectShell::SetFlags( SfxObjectShellFlags eFlags )
{
	pImp->eFlags = eFlags;
}

void SfxHeaderAttributes_Impl::SetAttributes()
{
	bAlert = sal_True;
	SvKeyValue aPair;
	for( sal_Bool bCont = xIter->GetFirst( aPair ); bCont;
		 bCont = xIter->GetNext( aPair ) )
		SetAttribute( aPair );
}

void SfxHeaderAttributes_Impl::SetAttribute( const SvKeyValue& rKV )
{
	String aValue = rKV.GetValue();
	if( rKV.GetKey().CompareIgnoreCaseToAscii( "refresh" ) == COMPARE_EQUAL && rKV.GetValue().Len() )
	{
		sal_uInt32 nTime = aValue.GetToken( 0, ';' ).ToInt32() ;
		String aURL = aValue.GetToken( 1, ';' );
		aURL.EraseTrailingChars().EraseLeadingChars();
        uno::Reference<document::XDocumentProperties> xDocProps(
            pDoc->getDocProperties());
		if( aURL.Copy(0, 4).CompareIgnoreCaseToAscii( "url=" ) == COMPARE_EQUAL )
		{
			INetURLObject aObj;
			INetURLObject( pDoc->GetMedium()->GetName() ).GetNewAbsURL( aURL.Copy( 4 ), &aObj );
            xDocProps->setAutoloadURL(
                aObj.GetMainURL( INetURLObject::NO_DECODE ) );
		}
        try
        {
            xDocProps->setAutoloadSecs( nTime );
        }
        catch (lang::IllegalArgumentException &)
        {
            // ignore
        }
	}
	else if( rKV.GetKey().CompareIgnoreCaseToAscii( "expires" ) == COMPARE_EQUAL )
	{
		DateTime aDateTime;
		if( INetRFC822Message::ParseDateField( rKV.GetValue(), aDateTime ) )
		{
			aDateTime.ConvertToLocalTime();
			pDoc->GetMedium()->SetExpired_Impl( aDateTime );
		}
		else
		{
//			DBG_ERROR( "Schlechtes ::com::sun::star::util::DateTime fuer Expired" );
			pDoc->GetMedium()->SetExpired_Impl( Date( 1, 1, 1970 ) );
		}
	}
	else if( rKV.GetKey().CompareIgnoreCaseToAscii( "content-type" ) == COMPARE_EQUAL )
	{
		::rtl::OString sContent = ::rtl::OUStringToOString( aValue, RTL_TEXTENCODING_ASCII_US );
		ByteString sType, sSubType;
		INetContentTypeParameterList aParameters;

		if( INetContentTypes::parse( sContent, sType, sSubType, &aParameters ) )
		{
			const INetContentTypeParameter * pCharset = aParameters.find("charset");
			if (pCharset != 0)
				pDoc->GetMedium()->SetCharset( pCharset->m_sValue );
		}
	}
}

void SfxHeaderAttributes_Impl::Append( const SvKeyValue& rKV )
{
	xIter->Append( rKV );
	if( bAlert ) SetAttribute( rKV );
}

SvKeyValueIterator* SfxObjectShell::GetHeaderAttributes()
{
	if( !pImp->xHeaderAttributes.Is() )
	{
		DBG_ASSERT( pMedium, "Kein Medium" );
		pImp->xHeaderAttributes = new SfxHeaderAttributes_Impl( this );
	}
	return ( SvKeyValueIterator*) &pImp->xHeaderAttributes;
}

void SfxObjectShell::ClearHeaderAttributesForSourceViewHack()
{
	((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
		->ClearForSourceView();
}


void SfxObjectShell::SetHeaderAttributesForSourceViewHack()
{
	((SfxHeaderAttributes_Impl*)GetHeaderAttributes())
		->SetAttributes();
}

sal_Bool SfxObjectShell::IsPreview() const
{
	if ( !pMedium )
		return sal_False;

	sal_Bool bPreview = sal_False;
	SFX_ITEMSET_ARG( pMedium->GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
	if ( pFlags )
	{
		// Werte auf einzelne Items verteilen
		String aFileFlags = pFlags->GetValue();
		aFileFlags.ToUpperAscii();
		if ( STRING_NOTFOUND != aFileFlags.Search( 'B' ) )
			bPreview = sal_True;
	}

	if ( !bPreview )
	{
		SFX_ITEMSET_ARG( pMedium->GetItemSet(), pItem, SfxBoolItem, SID_PREVIEW, sal_False);
		if ( pItem )
			bPreview = pItem->GetValue();
	}

	return bPreview;
}

sal_Bool SfxObjectShell::IsSecure()
{
	// Wenn globale Warnung an ist, nach Secure-Referer-Liste gehen
	String aReferer = GetMedium()->GetName();
	if ( !aReferer.Len() )
	{
		// bei neuen Dokumenten das Template als Referer nehmen
		::rtl::OUString aTempl( getDocProperties()->getTemplateURL() );
		if ( aTempl.getLength() )
            aReferer = INetURLObject( aTempl ).GetMainURL( INetURLObject::NO_DECODE );
	}

	INetURLObject aURL( "macro:" );
    if ( !aReferer.Len() )
        // empty new or embedded document
        return sal_True;

		SvtSecurityOptions aOpt;

	if( aOpt.GetBasicMode() == eALWAYS_EXECUTE )
    	return sal_True;

	if( aOpt.GetBasicMode() == eNEVER_EXECUTE )
    	return sal_False;

	if ( aOpt.IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
    //if ( SvtSecurityOptions().IsSecureURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), aReferer ) )
	{
        if ( GetMedium()->GetContent().is() )
        {
            Any aAny( ::utl::UCBContentHelper::GetProperty( aURL.GetMainURL( INetURLObject::NO_DECODE ), String( RTL_CONSTASCII_USTRINGPARAM("IsProtected")) ) );
            sal_Bool bIsProtected = sal_False;
            if ( ( aAny >>= bIsProtected ) && bIsProtected )
                return sal_False;
            else
                return sal_True;
		}
		else
			return sal_True;
	}
	else
		return sal_False;
}

void SfxObjectShell::SetWaitCursor( sal_Bool bSet ) const
{
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
    {
        if ( bSet )
            pFrame->GetFrame().GetWindow().EnterWait();
        else
            pFrame->GetFrame().GetWindow().LeaveWait();
    }
}

String SfxObjectShell::GetAPIName() const
{
	INetURLObject aURL( IsDocShared() ? GetSharedFileURL() : ::rtl::OUString( GetMedium()->GetName() ) );
    String aName( aURL.GetBase() );
    if( !aName.Len() )
        aName = aURL.GetURLNoPass();
    if ( !aName.Len() )
        aName = GetTitle( SFX_TITLE_DETECT );
    return aName;
}

void SfxObjectShell::Invalidate( sal_uInt16 nId )
{
    for( SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); pFrame; pFrame = SfxViewFrame::GetNext( *pFrame, this ) )
        Invalidate_Impl( pFrame->GetBindings(), nId );
}

bool SfxObjectShell::AdjustMacroMode( const String& /*rScriptType*/, bool bSuppressUI )
{
    uno::Reference< task::XInteractionHandler > xInteraction;
    if ( pMedium && !bSuppressUI )
        xInteraction = pMedium->GetInteractionHandler();

    CheckForBrokenDocSignatures_Impl( xInteraction );

    CheckEncryption_Impl( xInteraction );

    return pImp->aMacroMode.adjustMacroMode( xInteraction );
}

Window* SfxObjectShell::GetDialogParent( SfxMedium* pLoadingMedium )
{
    Window* pWindow = 0;
    SfxItemSet* pSet = pLoadingMedium ? pLoadingMedium->GetItemSet() : GetMedium()->GetItemSet();
    SFX_ITEMSET_ARG( pSet, pUnoItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False );
    if ( pUnoItem )
    {
        uno::Reference < frame::XFrame > xFrame( pUnoItem->GetFrame() );
        pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
    }

    if ( !pWindow )
    {
        SfxFrame* pFrame = 0;
        SFX_ITEMSET_ARG( pSet, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False );
        if( pFrameItem && pFrameItem->GetFrame() )
            // get target frame from ItemSet
            pFrame = pFrameItem->GetFrame();
        else
        {
            // try the current frame
            SfxViewFrame* pView = SfxViewFrame::Current();
            if ( !pView || pView->GetObjectShell() != this )
                // get any visible frame
                pView = SfxViewFrame::GetFirst(this);
            if ( pView )
                pFrame = &pView->GetFrame();
        }

        if ( pFrame )
            // get topmost window
            pWindow = VCLUnoHelper::GetWindow( pFrame->GetFrameInterface()->getContainerWindow() );
    }

    if ( pWindow )
    {
        // this frame may be invisible, show it if it is allowed
        SFX_ITEMSET_ARG( pSet, pHiddenItem, SfxBoolItem, SID_HIDDEN, sal_False );
        if ( !pHiddenItem || !pHiddenItem->GetValue() )
        {
            pWindow->Show();
            pWindow->ToTop();
        }
    }

    return pWindow;
}

String SfxObjectShell::UpdateTitle( SfxMedium* pMed, sal_uInt16 nDocViewNumber )
{
    // Titel des Fensters
    String aTitle;
    if ( pMed )
	{
		INetURLObject aTmp( pMed->GetName() );
        aTitle = aTmp.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
	}
    else
    {
		pMed = GetMedium();
        aTitle = GetTitle(SFX_TITLE_CAPTION);
        String aName(aTitle);
        if ( nDocViewNumber )
        {
            aName += ':';
            aName += String::CreateFromInt32( nDocViewNumber );
        }
    }

	if ( pMed )
	{
		SFX_ITEMSET_ARG( pMed->GetItemSet(), pRepairedDocItem, SfxBoolItem, SID_REPAIRPACKAGE, sal_False );
		if ( pRepairedDocItem && pRepairedDocItem->GetValue() )
        	aTitle += String( SfxResId(STR_REPAIREDDOCUMENT) );
	}

	if ( IsReadOnlyUI() || (pMed && pMed->IsReadOnly()) )
        aTitle += String( SfxResId(STR_READONLY) );
    else if ( IsDocShared() )
        aTitle += String( SfxResId(STR_SHARED) );

    return aTitle;
}

void SfxObjectShell::SetCreateMode_Impl( SfxObjectCreateMode nMode )
{
	eCreateMode = nMode;
}

sal_Bool SfxObjectShell::IsInPlaceActive()
{
	if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
		return sal_False;

    SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
    return pFrame && pFrame->GetFrame().IsInPlace();
}

sal_Bool SfxObjectShell::IsUIActive()
{
	if ( eCreateMode != SFX_CREATE_MODE_EMBEDDED )
		return sal_False;

    SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
    return pFrame && pFrame->GetFrame().IsInPlace() && pFrame->GetFrame().GetWorkWindow_Impl()->IsVisible_Impl();
}

void SfxObjectShell::UIActivate( sal_Bool )
{
}

void SfxObjectShell::InPlaceActivate( sal_Bool )
{
}

sal_Bool SfxObjectShell::UseInteractionToHandleError(
                    const uno::Reference< task::XInteractionHandler >& xHandler,
                    sal_uInt32 nError )
{
    sal_Bool bResult = sal_False;

    if ( xHandler.is() )
    {
        try
        {
            uno::Any aInteraction;
            uno::Sequence< uno::Reference< task::XInteractionContinuation > > lContinuations(2);
            ::comphelper::OInteractionAbort* pAbort = new ::comphelper::OInteractionAbort();
            ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove();
            lContinuations[0] = uno::Reference< task::XInteractionContinuation >(
                                 static_cast< task::XInteractionContinuation* >( pAbort ), uno::UNO_QUERY );
            lContinuations[1] = uno::Reference< task::XInteractionContinuation >(
                                 static_cast< task::XInteractionContinuation* >( pApprove ), uno::UNO_QUERY );

            task::ErrorCodeRequest aErrorCode;
            aErrorCode.ErrCode = nError;
            aInteraction <<= aErrorCode;
            xHandler->handle(::framework::InteractionRequest::CreateRequest (aInteraction,lContinuations));
            bResult = pAbort->wasSelected();
        }
        catch( uno::Exception& )
        {}
    }

    return bResult;
}

sal_Bool SfxObjectShell_Impl::NeedsOfficeUpdateDialog()
{
    // if the configuration is not available for any reason, the default behavior is to show the message
    sal_Bool bResult = sal_True;

    try
    {
    	uno::Reference< lang::XMultiServiceFactory > xServiceManager( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
		uno::Reference< uno::XInterface > xCommonConfig(
                        ::comphelper::ConfigurationHelper::openConfig(
							xServiceManager,
							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common" ) ),
							::comphelper::ConfigurationHelper::E_STANDARD ),
                        uno::UNO_SET_THROW );

        ::comphelper::ConfigurationHelper::readRelativeKey(
                        xCommonConfig,
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Load/" ) ),
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ShowOfficeUpdateDialog" ) ) ) >>= bResult;
    }
    catch( uno::Exception& )
    {
    }

	return bResult;
}

sal_Int16 SfxObjectShell_Impl::getCurrentMacroExecMode() const
{
    sal_Int16 nImposedExecMode( MacroExecMode::NEVER_EXECUTE );

    const SfxMedium* pMedium( rDocShell.GetMedium() );
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
    if ( pMedium )
    {
        SFX_ITEMSET_ARG( pMedium->GetItemSet(), pMacroModeItem, SfxUInt16Item, SID_MACROEXECMODE, sal_False);
        if ( pMacroModeItem )
            nImposedExecMode = pMacroModeItem->GetValue();
    }
    return nImposedExecMode;
}

sal_Bool SfxObjectShell_Impl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
{
    const SfxMedium* pMedium( rDocShell.GetMedium() );
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getCurrentMacroExecMode: no medium!" );
    if ( pMedium )
    {
		pMedium->GetItemSet()->Put( SfxUInt16Item( SID_MACROEXECMODE, nMacroMode ) );
        return sal_True;
    }

    return sal_False;
}

::rtl::OUString SfxObjectShell_Impl::getDocumentLocation() const
{
    ::rtl::OUString sLocation;

    const SfxMedium* pMedium( rDocShell.GetMedium() );
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getDocumentLocation: no medium!" );
    if ( pMedium )
    {
        sLocation = pMedium->GetName();
        if ( !sLocation.getLength() )
        {
            // for documents made from a template: get the name of the template
            sLocation = rDocShell.getDocProperties()->getTemplateURL();
        }
    }
    return sLocation;
}

uno::Reference< embed::XStorage > SfxObjectShell_Impl::getZipStorageToSign()
{
    Reference < embed::XStorage > xStore;

    SfxMedium* pMedium( rDocShell.GetMedium() );
    OSL_PRECOND( pMedium, "SfxObjectShell_Impl::getLastCommitDocumentStorage: no medium!" );
    if ( pMedium )
        xStore = pMedium->GetZipStorageToSign_Impl();

    return xStore;
}

sal_Bool SfxObjectShell_Impl::documentStorageHasMacros() const
{
    return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage );
}

Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const
{
    return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY );
}

sal_Int16 SfxObjectShell_Impl::getScriptingSignatureState()
{
    sal_Int16 nSignatureState( rDocShell.GetScriptingSignatureState() );

    if ( nSignatureState != SIGNATURESTATE_NOSIGNATURES && m_bMacroSignBroken )
    {
        // if there is a macro signature it must be handled as broken
        nSignatureState = SIGNATURESTATE_SIGNATURES_BROKEN;
    }

    return nSignatureState;
}

sal_Bool SfxObjectShell_Impl::hasTrustedScriptingSignature( sal_Bool bAllowUIToAddAuthor )
{
    sal_Bool bResult = sal_False;

    try
    {
        ::rtl::OUString aVersion;
        try
        {
            uno::Reference < beans::XPropertySet > xPropSet( rDocShell.GetStorage(), uno::UNO_QUERY_THROW );
            xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ) ) >>= aVersion;
        }
        catch( uno::Exception& )
        {
        }
        uno::Sequence< uno::Any > aArgs( 1 );
        aArgs[0] <<= aVersion;

        uno::Reference< security::XDocumentDigitalSignatures > xSigner( comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.security.DocumentDigitalSignatures" ) ), aArgs ), uno::UNO_QUERY_THROW );

        if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN
          || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
          || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
        {
            uno::Sequence< security::DocumentSignatureInformation > aInfo = rDocShell.ImplAnalyzeSignature( sal_True, xSigner );

            if ( aInfo.getLength() )
            {
                if ( nScriptingSignatureState == SIGNATURESTATE_UNKNOWN )
                    nScriptingSignatureState = rDocShell.ImplCheckSignaturesInformation( aInfo );

                if ( nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_OK
                  || nScriptingSignatureState == SIGNATURESTATE_SIGNATURES_NOTVALIDATED )
                {
                    for ( sal_Int32 nInd = 0; !bResult && nInd < aInfo.getLength(); nInd++ )
                    {
                        bResult = xSigner->isAuthorTrusted( aInfo[nInd].Signer );
                    }

                    if ( !bResult && bAllowUIToAddAuthor )
                    {
                        uno::Reference< task::XInteractionHandler > xInteraction;
                        if ( rDocShell.GetMedium() )
                            xInteraction = rDocShell.GetMedium()->GetInteractionHandler();

                        if ( xInteraction.is() )
                        {
                            task::DocumentMacroConfirmationRequest aRequest;
                            aRequest.DocumentURL = getDocumentLocation();
                            aRequest.DocumentStorage = rDocShell.GetMedium()->GetZipStorageToSign_Impl();
                            aRequest.DocumentSignatureInformation = aInfo;
                            aRequest.DocumentVersion = aVersion;
                            aRequest.Classification = task::InteractionClassification_QUERY;
                            bResult = SfxMedium::CallApproveHandler( xInteraction, uno::makeAny( aRequest ), sal_True );
                        }
                    }
                }
            }
        }
    }
    catch( uno::Exception& )
    {}

    return bResult;
}

void SfxObjectShell_Impl::showBrokenSignatureWarning( const uno::Reference< task::XInteractionHandler >& _rxInteraction ) const
{
    if  ( !bSignatureErrorIsShown )
    {
        SfxObjectShell::UseInteractionToHandleError( _rxInteraction, ERRCODE_SFX_BROKENSIGNATURE );
	    const_cast< SfxObjectShell_Impl* >( this )->bSignatureErrorIsShown = sal_True;
    }
}

void SfxObjectShell::AddLog( const ::rtl::OUString& aMessage )
{
    if ( !pImp->m_xLogRing.is() )
    {
        try
        {
            ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            if ( aContext.is() )
                pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
        }
        catch( uno::Exception& )
        {}
    }

    if ( pImp->m_xLogRing.is() )
        pImp->m_xLogRing->logString( aMessage );
}

namespace {

void WriteStringInStream( const uno::Reference< io::XOutputStream >& xOutStream, const ::rtl::OUString& aString )
{
    if ( xOutStream.is() )
    {
        ::rtl::OString aStrLog = ::rtl::OUStringToOString( aString, RTL_TEXTENCODING_UTF8 );
        uno::Sequence< sal_Int8 > aLogData( (const sal_Int8*)aStrLog.getStr(), aStrLog.getLength() );
        xOutStream->writeBytes( aLogData );

        aLogData.realloc( 1 );
        aLogData[0] = '\n';
        xOutStream->writeBytes( aLogData );
    }
}

}

void SfxObjectShell::StoreLog()
{
    if ( !pImp->m_xLogRing.is() )
    {
        try
        {
            ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
            if ( aContext.is() )
                pImp->m_xLogRing.set( aContext.getSingleton( "com.sun.star.logging.DocumentIOLogRing" ), UNO_QUERY_THROW );
        }
        catch( uno::Exception& )
        {}
    }

    if ( pImp->m_xLogRing.is() )
    {
        ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}" ) );
//#ifdef WNT
//        ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}" ) );
//#else
//        ::rtl::OUString aFileURL = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/bootstraprc:UserInstallation}" ) );
//#endif
        ::rtl::Bootstrap::expandMacros( aFileURL );

//#ifdef WNT
//        ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/setup.ini:buildid}" ) );
//#else
//        ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/setuprc:buildid}" ) );
//#endif
        ::rtl::OUString aBuildID = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("setup") ":buildid}" ) );
        ::rtl::Bootstrap::expandMacros( aBuildID );

        if ( aFileURL.getLength() )
        {
            aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/temp/document_io_logring.txt" ) );
            try
            {
                uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_SET_THROW );
                uno::Reference< ucb::XSimpleFileAccess > xSimpleFileAccess( xFactory->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.ucb.SimpleFileAccess" ) ), uno::UNO_QUERY_THROW );
                uno::Reference< io::XStream > xStream( xSimpleFileAccess->openFileReadWrite( aFileURL ), uno::UNO_SET_THROW );
                uno::Reference< io::XOutputStream > xOutStream( xStream->getOutputStream(), uno::UNO_SET_THROW );
                uno::Reference< io::XTruncate > xTruncate( xOutStream, uno::UNO_QUERY_THROW );
                xTruncate->truncate();

                if ( aBuildID.getLength() )
                    WriteStringInStream( xOutStream, aBuildID );

                uno::Sequence< ::rtl::OUString > aLogSeq = pImp->m_xLogRing->getCollectedLog();
                for ( sal_Int32 nInd = 0; nInd < aLogSeq.getLength(); nInd++ )
                    WriteStringInStream( xOutStream, aLogSeq[nInd] );
            }
            catch( uno::Exception& )
            {}
        }
    }
}
