/**************************************************************
 * 
 * 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_sc.hxx"
// System - Includes -----------------------------------------------------

#include "scitems.hxx"
#include <editeng/eeitem.hxx>
#include <editeng/svxenum.hxx>
#include <svx/algitem.hxx>

#include <sot/clsids.hxx>
#include <unotools/securityoptions.hxx>
#include <tools/stream.hxx>
#include <tools/string.hxx>
#include <tools/urlobj.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/virdev.hxx>
#include <vcl/waitobj.hxx>
#include <svtools/ctrltool.hxx>
#include <svtools/sfxecode.hxx>
#include <svl/zforlist.hxx>
#include <svl/PasswordHelper.hxx>
#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dinfdlg.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/evntconf.hxx>
#include <sfx2/sfx.hrc>
#include <sfx2/objface.hxx>
#include <svl/srchitem.hxx>
#include <unotools/fltrcfg.hxx>
#include <svl/documentlockfile.hxx>
#include <svl/sharecontrolfile.hxx>
#include <unotools/charclass.hxx>
#include <vcl/virdev.hxx>
#include "chgtrack.hxx"
#include "chgviset.hxx"
#include <sfx2/request.hxx>
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <com/sun/star/script/vba/VBAEventId.hpp>
#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
#include <com/sun/star/sheet/XSpreadsheetView.hpp>
#include <com/sun/star/task/XJob.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <basic/sbstar.hxx>
#include <basic/basmgr.hxx>

#include "scabstdlg.hxx" //CHINA001
#include <sot/formats.hxx>
#define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC

// INCLUDE ---------------------------------------------------------------

#include "cell.hxx"
#include "global.hxx"
#include "filter.hxx"
#include "scmod.hxx"
#include "tabvwsh.hxx"
#include "docfunc.hxx"
#include "imoptdlg.hxx"
#include "impex.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "scerrors.hxx"
#include "brdcst.hxx"
#include "stlpool.hxx"
#include "autostyl.hxx"
#include "attrib.hxx"
#include "asciiopt.hxx"
#include "waitoff.hxx"
#include "docpool.hxx"		// LoadCompleted
#include "progress.hxx"
#include "pntlock.hxx"
#include "collect.hxx"
#include "docuno.hxx"
#include "appoptio.hxx"
#include "detdata.hxx"
#include "printfun.hxx"
#include "dociter.hxx"
#include "cellform.hxx"
#include "chartlis.hxx"
#include "hints.hxx"
#include "xmlwrap.hxx"
#include "drwlayer.hxx"
#include "refreshtimer.hxx"
#include "dbcolect.hxx"
#include "scextopt.hxx"
#include "compiler.hxx"
#include "cfgids.hxx"
#include "warnpassword.hxx"
#include "optsolver.hxx"
#include "sheetdata.hxx"
#include "tabprotection.hxx"
#include "dpobject.hxx"

#include "docsh.hxx"
#include "docshimp.hxx"
#include <rtl/logfile.hxx>

#include <comphelper/processfactory.hxx>
#include "uiitems.hxx"
#include "cellsuno.hxx"

using namespace com::sun::star;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;

// STATIC DATA -----------------------------------------------------------

//	Stream-Namen im Storage

const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM;		// "StarCalcDocument"
const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets";

//	Filter-Namen (wie in sclib.cxx)

static const sal_Char __FAR_DATA pFilterSc50[]		= "StarCalc 5.0";
//static const sal_Char __FAR_DATA pFilterSc50Temp[]	= "StarCalc 5.0 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterSc40[]		= "StarCalc 4.0";
//static const sal_Char __FAR_DATA pFilterSc40Temp[]	= "StarCalc 4.0 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterSc30[]		= "StarCalc 3.0";
//static const sal_Char __FAR_DATA pFilterSc30Temp[]	= "StarCalc 3.0 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterSc10[]		= "StarCalc 1.0";
static const sal_Char __FAR_DATA pFilterXML[]		= "StarOffice XML (Calc)";
static const sal_Char __FAR_DATA pFilterAscii[]		= "Text - txt - csv (StarCalc)";
static const sal_Char __FAR_DATA pFilterLotus[]		= "Lotus";
static const sal_Char __FAR_DATA pFilterQPro6[]		= "Quattro Pro 6.0";
static const sal_Char __FAR_DATA pFilterExcel4[]	= "MS Excel 4.0";
static const sal_Char __FAR_DATA pFilterEx4Temp[]	= "MS Excel 4.0 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterExcel5[]	= "MS Excel 5.0/95";
static const sal_Char __FAR_DATA pFilterEx5Temp[]	= "MS Excel 5.0/95 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterExcel95[]	= "MS Excel 95";
static const sal_Char __FAR_DATA pFilterEx95Temp[]	= "MS Excel 95 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterExcel97[]	= "MS Excel 97";
static const sal_Char __FAR_DATA pFilterEx97Temp[]	= "MS Excel 97 Vorlage/Template";
static const sal_Char __FAR_DATA pFilterEx07Xml[]   = "MS Excel 2007 XML";
static const sal_Char __FAR_DATA pFilterDBase[]		= "dBase";
static const sal_Char __FAR_DATA pFilterDif[]		= "DIF";
static const sal_Char __FAR_DATA pFilterSylk[]		= "SYLK";
static const sal_Char __FAR_DATA pFilterHtml[]		= "HTML (StarCalc)";
static const sal_Char __FAR_DATA pFilterHtmlWebQ[]	= "calc_HTML_WebQuery";
static const sal_Char __FAR_DATA pFilterRtf[]		= "Rich Text Format (StarCalc)";

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

#define ScDocShell
#include "scslots.hxx"

namespace
{
    template< bool bByName >
    inline sal_uInt8 GetMediumFlag( const String & rName )
    {
        sal_uInt8 bResult = E_MEDIUM_FLAG_NONE;

#define SFX2_FILTER_ENTRY( entry ) { #entry, (sizeof #entry)/sizeof((#entry)[0]) - 1 },
        static const struct
        {
            const char * mpFilterTypeName;
            unsigned mnFilterTypeLen;
        } szMSFilterTypes [] = 
        {
            SFX2_FILTER_ENTRY(calc_MS_Excel_40)
            SFX2_FILTER_ENTRY(calc_MS_Excel_40_VorlageTemplate)
            SFX2_FILTER_ENTRY(calc_MS_Excel_5095)
            SFX2_FILTER_ENTRY(calc_MS_Excel_5095_VorlageTemplate)
            SFX2_FILTER_ENTRY(calc_MS_Excel_95)
            SFX2_FILTER_ENTRY(calc_MS_Excel_95_VorlageTemplate)
            SFX2_FILTER_ENTRY(calc_MS_Excel_97)
            SFX2_FILTER_ENTRY(calc_MS_Excel_97_VorlageTemplate)
            SFX2_FILTER_ENTRY(calc_MS_Excel_2003_XML)
            SFX2_FILTER_ENTRY(MS Excel 2007 XML)
            SFX2_FILTER_ENTRY(MS Excel 2007 XML Template)
            SFX2_FILTER_ENTRY(MS Excel 2007 Binary)
        };

        static const struct
        {
            const char * mpFilterName;
            unsigned mnFilterNameLen;
        } szMSFilterNames [] = 
        {
            { pFilterExcel4, strlen( pFilterExcel4 ) },
            { pFilterEx4Temp, strlen( pFilterEx4Temp ) },
            { pFilterExcel95, strlen( pFilterExcel95 ) },
            { pFilterEx95Temp, strlen( pFilterEx95Temp ) },
            { pFilterExcel5, strlen( pFilterExcel5 ) },
            { pFilterEx5Temp, strlen( pFilterEx5Temp ) },
            { pFilterExcel97, strlen( pFilterExcel97 ) },
            { pFilterEx97Temp, strlen( pFilterEx97Temp ) },
            SFX2_FILTER_ENTRY(Microsoft Excel 2003 XML)
            { pFilterEx07Xml, strlen( pFilterEx07Xml ) },
            SFX2_FILTER_ENTRY(Microsoft Excel 2007 XML Template)
            SFX2_FILTER_ENTRY(Microsoft Excel 2007 Binary)
        };

        enum{
            e_calc_MS_Excel_40,
            e_calc_MS_Excel_40_VorlageTemplate,
            e_calc_MS_Excel_5095,
            e_calc_MS_Excel_5095_VorlageTemplate,
            e_calc_MS_Excel_95,
            Se_calc_MS_Excel_95_VorlageTemplate,
            e_calc_MS_Excel_97,
            e_calc_MS_Excel_97_VorlageTemplate,
            e_calc_MS_Excel_2003_XML,
            e_MS_Excel_2007_XML,
            e_MS_Excel_2007_XML_Template,
            e_MS_Excel_2007_Binary
        };

#undef SFX2_FILTER_ENTRY

        if( bByName )
        {
            for( unsigned i = 0; i < (sizeof szMSFilterNames)/sizeof(szMSFilterNames[0] ); i++ )
                if( rName.Len() == szMSFilterNames[i].mnFilterNameLen 
                    && std::equal( szMSFilterNames[i].mpFilterName, szMSFilterNames[i].mpFilterName + szMSFilterNames[i].mnFilterNameLen, rName.GetBuffer() ) )
                    bResult |= ( E_MEDIUM_FLAG_EXCEL | ( ( i == e_MS_Excel_2007_XML ) * E_MEDIUM_FLAG_MSXML ) );
        }
        else
        {
            for( unsigned i = 0; i < (sizeof szMSFilterTypes)/sizeof(szMSFilterTypes[0] ); i++ )
                if( rName.Len() == szMSFilterTypes[i].mnFilterTypeLen 
                    && std::equal( szMSFilterTypes[i].mpFilterTypeName, szMSFilterTypes[i].mpFilterTypeName + szMSFilterTypes[i].mnFilterTypeLen, rName.GetBuffer() ) )
                    bResult |= ( E_MEDIUM_FLAG_EXCEL | ( ( i == e_MS_Excel_2007_XML ) * E_MEDIUM_FLAG_MSXML ) );
        }

        return bResult;
    }

    inline sal_uInt8 GetMediumFlag( const SfxMedium * pMedium )
    {
        if( const SfxFilter * pFilter = pMedium ? pMedium->GetFilter() : NULL )
            return GetMediumFlag<false>( pFilter->GetTypeName() );

        return E_MEDIUM_FLAG_NONE;
    }
}

SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL))
{
	SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
}

//	GlobalName der aktuellen Version:
SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "scalc" )

TYPEINIT1( ScDocShell, SfxObjectShell );		// SfxInPlaceObject: kein Type-Info ?

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

void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName,
										sal_uInt32* pFormat,
                                        String* /* pAppName */,
										String* pFullTypeName,
										String* pShortTypeName,
                                        sal_Int32 nFileFormat,
                                        sal_Bool bTemplate /* = sal_False */) const
{
	if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
	{
		*pClassName		= SvGlobalName( SO3_SC_CLASSID_60 );
		*pFormat		= SOT_FORMATSTR_ID_STARCALC_60;
		*pFullTypeName	= String( ScResId( SCSTR_LONG_SCDOC_NAME ) );
		*pShortTypeName	= String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
	}
	else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
	{
		*pClassName		= SvGlobalName( SO3_SC_CLASSID_60 );
        *pFormat		= bTemplate ? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE : SOT_FORMATSTR_ID_STARCALC_8;
		*pFullTypeName	= String( RTL_CONSTASCII_USTRINGPARAM("calc8") );
		*pShortTypeName	= String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
	}
	else
	{
		DBG_ERROR("wat fuer ne Version?");
	}
}

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

void ScDocShell::DoEnterHandler()
{
	ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
	if (pViewSh)
		if (pViewSh->GetViewData()->GetDocShell() == this)
			SC_MOD()->InputEnterHandler();
}

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

SCTAB ScDocShell::GetSaveTab()
{
	SCTAB nTab = 0;
	ScTabViewShell* pSh = GetBestViewShell();
	if (pSh)
	{
		const ScMarkData& rMark = pSh->GetViewData()->GetMarkData();
		for ( nTab = 0; nTab <= MAXTAB; nTab++ )	// erste markierte Tabelle
			if ( rMark.GetTableSelect( nTab ) )
				break;
	}
	return nTab;
}

sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates )
{
	// get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
    sal_uInt16 nState = SfxObjectShell::GetHiddenInformationState( nStates );

	if ( nStates & HIDDENINFORMATION_RECORDEDCHANGES )
    {
        if ( aDocument.GetChangeTrack() && aDocument.GetChangeTrack()->GetFirst() )
          nState |= HIDDENINFORMATION_RECORDEDCHANGES;
    }
    if ( nStates & HIDDENINFORMATION_NOTES )
    {
        SCTAB nTableCount = aDocument.GetTableCount();
        SCTAB nTable = 0;
        sal_Bool bFound(sal_False);
	    while ( nTable < nTableCount && !bFound )
	    {
            ScCellIterator aCellIter( &aDocument, 0,0, nTable, MAXCOL,MAXROW, nTable );
            for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bFound; pCell = aCellIter.GetNext() )
                if (pCell->HasNote())
                    bFound = sal_True;
            nTable++;
        }

        if (bFound)
            nState |= HIDDENINFORMATION_NOTES;
    }

	return nState;
}

void ScDocShell::BeforeXMLLoading()
{
    aDocument.DisableIdle( sal_True );

    // prevent unnecessary broadcasts and updates
    DBG_ASSERT(pModificator == NULL, "The Modificator should not exist");
	pModificator = new ScDocShellModificator( *this );

    aDocument.SetImportingXML( sal_True );
    aDocument.EnableExecuteLink( false );   // #i101304# to be safe, prevent nested loading from external references
    aDocument.EnableUndo( sal_False );
	// prevent unnecessary broadcasts and "half way listeners"
	aDocument.SetInsertingFromOtherDoc( sal_True );

	if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
		ScColumn::bDoubleAlloc = sal_True;
}

void ScDocShell::AfterXMLLoading(sal_Bool bRet)
{
	if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
	{
		UpdateLinks();
		// don't prevent establishing of listeners anymore
		aDocument.SetInsertingFromOtherDoc( sal_False );
		if ( bRet )
		{
			ScChartListenerCollection* pChartListener = aDocument.GetChartListenerCollection();
			if (pChartListener)
				pChartListener->UpdateDirtyCharts();

			// #95582#; set the table names of linked tables to the new path
			SCTAB nTabCount = aDocument.GetTableCount();
			for (SCTAB i = 0; i < nTabCount; ++i)
			{
				if (aDocument.IsLinked( i ))
				{
					String aName;
					aDocument.GetName(i, aName);
					String aLinkTabName = aDocument.GetLinkTab(i);
					xub_StrLen nLinkTabNameLength = aLinkTabName.Len();
					xub_StrLen nNameLength = aName.Len();
					if (nLinkTabNameLength < nNameLength)
					{

						// remove the quottes on begin and end of the docname and restore the escaped quotes
						const sal_Unicode* pNameBuffer = aName.GetBuffer();
						if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
							ScGlobal::UnicodeStrChr( pNameBuffer, SC_COMPILER_FILE_TAB_SEP ) )
						{
							rtl::OUStringBuffer aDocURLBuffer;
							sal_Bool bQuote = sal_True;			// Dokumentenname ist immer quoted
							++pNameBuffer;
							while ( bQuote && *pNameBuffer )
							{
								if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
									bQuote = sal_False;
								else if( !(*pNameBuffer == '\\' && *(pNameBuffer+1) == '\'') )
									aDocURLBuffer.append(*pNameBuffer);		// falls escaped Quote: nur Quote in den Namen
								++pNameBuffer;
							}


							if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP )  // after the last quote of the docname should be the # char
							{
								xub_StrLen nIndex = nNameLength - nLinkTabNameLength;
								INetURLObject aINetURLObject(aDocURLBuffer.makeStringAndClear());
								if(	aName.Equals(aLinkTabName, nIndex, nLinkTabNameLength) &&
									(aName.GetChar(nIndex - 1) == '#') && // before the table name should be the # char
									!aINetURLObject.HasError()) // the docname should be a valid URL
								{
                        	    	aName = ScGlobal::GetDocTabName( aDocument.GetLinkDoc( i ), aDocument.GetLinkTab( i ) );
	                            	aDocument.RenameTab(i, aName, sal_True, sal_True);
								}
								// else;  nothing has to happen, because it is a user given name
							}
							// else;  nothing has to happen, because it is a user given name
						}
						// else;  nothing has to happen, because it is a user given name
					}
					// else;  nothing has to happen, because it is a user given name
				}
			}

            // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
            // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
            ScDPCollection* pDPCollection = aDocument.GetDPCollection();
            if ( pDPCollection )
            {
                sal_uInt16 nDPCount = pDPCollection->GetCount();
                for (sal_uInt16 nDP=0; nDP<nDPCount; nDP++)
                {
                    ScDPObject* pDPObj = (*pDPCollection)[nDP];
                    if ( !pDPObj->GetName().Len() )
                        pDPObj->SetName( pDPCollection->CreateNewName() );
                }
            }
		}
		ScColumn::bDoubleAlloc = sal_False;
    }
    else
		aDocument.SetInsertingFromOtherDoc( sal_False );
		
	aDocument.SetImportingXML( sal_False );
    aDocument.EnableExecuteLink( true );
    aDocument.EnableUndo( sal_True );
    bIsEmpty = sal_False;

    if (pModificator)
    {
        delete pModificator;
        pModificator = NULL;
    }
    else
    {
        DBG_ERROR("The Modificator should exist");
    }

    aDocument.DisableIdle( sal_False );
}

sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" );

	//	MacroCallMode is no longer needed, state is kept in SfxObjectShell now

	// no Seek(0) here - always loading from storage, GetInStream must not be called

    BeforeXMLLoading();

    // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
    // from an external component. The XMLFromWrapper flag is only set here, when called
    // through ScDocShell.
    aDocument.SetXMLFromWrapper( sal_True );

    ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor );

    sal_Bool bRet(sal_False);
    ErrCode nError = ERRCODE_NONE;
	if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
        bRet = aImport.Import(sal_False, nError);
	else
        bRet = aImport.Import(sal_True, nError);

    if ( nError )
        pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );

    aDocument.SetXMLFromWrapper( sal_False );
    AfterXMLLoading(bRet);

	//!	row heights...

	return bRet;
}

sal_Bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::SaveXML" );

    aDocument.DisableIdle( sal_True );

    ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor );
	sal_Bool bRet(sal_False);
	if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
		bRet = aImport.Export(sal_False);
	else
		bRet = aImport.Export(sal_True);

    aDocument.DisableIdle( sal_False );

    return bRet;
}

sal_Bool __EXPORT ScDocShell::Load( SfxMedium& rMedium )
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

	//	only the latin script language is loaded
	//	-> initialize the others from options (before loading)
    InitOptions(true);

	GetUndoManager()->Clear();

    sal_Bool bRet = SfxObjectShell::Load( rMedium );
	if( bRet )
	{
        if (GetMedium())
        {
            SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
            nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
        }

		{
			//	prepare a valid document for XML filter
			//	(for ConvertFrom, InitNew is called before)
			aDocument.MakeTable(0);
			aDocument.GetStyleSheetPool()->CreateStandardStyles();
			aDocument.UpdStlShtPtrsFrmNms();

            bRet = LoadXML( &rMedium, NULL );
		}
	}

    if (!bRet && !rMedium.GetError())
        rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );

    if (rMedium.GetError())
        SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );

	InitItems();
	CalcOutputFactor();

	// #73762# invalidate eventually temporary table areas
	if ( bRet )
		aDocument.InvalidateTableArea();

	bIsEmpty = sal_False;
	FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
	return bRet;
}

void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
    if (rHint.ISA(ScTablesHint) )
    {
        const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint );
        if (rScHint.GetId() == SC_TAB_INSERTED)
        {
            uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor();
            if ( xVbaEvents.is() ) try
            {
                uno::Sequence< uno::Any > aArgs( 1 );
                aArgs[0] <<= rScHint.GetTab1();
                xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs );
            }
            catch( uno::Exception& )
            {
            }
        }
    }

	if (rHint.ISA(SfxSimpleHint))								// ohne Parameter
	{
		sal_uLong nSlot = ((const SfxSimpleHint&)rHint).GetId();
		switch ( nSlot )
		{
			case SFX_HINT_TITLECHANGED:
				aDocument.SetName( SfxShell::GetName() );
				//	RegisterNewTargetNames gibts nicht mehr
				SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED ));	// Navigator
				break;
		}
	}
	else if (rHint.ISA(SfxStyleSheetHint))						// Vorlagen geaendert
		NotifyStyle((const SfxStyleSheetHint&) rHint);
	else if (rHint.ISA(ScAutoStyleHint))
	{
		//!	direct call for AutoStyles

		//	this is called synchronously from ScInterpreter::ScStyle,
		//	modifying the document must be asynchronous
		//	(handled by AddInitial)

		ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint;
		ScRange aRange = rStlHint.GetRange();
		String aName1 = rStlHint.GetStyle1();
		String aName2 = rStlHint.GetStyle2();
		sal_uInt32 nTimeout = rStlHint.GetTimeout();

		if (!pAutoStyleList)
			pAutoStyleList = new ScAutoStyleList(this);
		pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
	}
    else if ( rHint.ISA( SfxEventHint ) )
    {
        sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
        switch ( nEventId )
        {
            case SFX_EVENT_LOADFINISHED:
                {
                    // the readonly documents should not be opened in shared mode
                    if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
                    {
                        if ( SwitchToShared( sal_True, sal_False ) )
                        {
                            ScViewData* pViewData = GetViewData();
                            ScTabView* pTabView = ( pViewData ? dynamic_cast< ScTabView* >( pViewData->GetView() ) : NULL );
                            if ( pTabView )
                            {
                                pTabView->UpdateLayerLocks();
                            }
                        }
                        else
                        {
                            // switching to shared mode has failed, the document should be opened readonly
                            // TODO/LATER: And error message should be shown here probably
                            SetReadOnlyUI( sal_True );
                        }
                    }
                }
                break;
            case SFX_EVENT_VIEWCREATED:
                {
                    if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
                    {
                        ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
                        if ( aAppOptions.GetShowSharedDocumentWarning() )
                        {
                            WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
                                ScGlobal::GetRscString( STR_SHARED_DOC_WARNING ) );
                            aBox.SetDefaultCheckBoxText();
                            aBox.Execute();
                            sal_Bool bChecked = aBox.GetCheckBoxState();
                            if ( bChecked )
                            {
                                aAppOptions.SetShowSharedDocumentWarning( !bChecked );
                                SC_MOD()->SetAppOptions( aAppOptions );
                            }
                        }
                    }

                    try
                    {
                        uno::Reference< uno::XComponentContext > xContext;
                        uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
                        uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW );
                        xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;
                        if ( xContext.is() )
                        {
                            uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW );
                            uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration(
                                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) );
                            if ( xEnum.is() )
                            {
                                while ( xEnum->hasMoreElements() )
                                {
                                    uno::Any aAny = xEnum->nextElement();
                                    uno::Reference< lang::XSingleComponentFactory > xFactory;
                                    aAny >>= xFactory;
                                    if ( xFactory.is() )
                                    {
                                        uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
                                        uno::Sequence< beans::NamedValue > aArgsForJob(1);
                                        ScViewData* pViewData = GetViewData();
                                        SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL );
                                        SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL );
                                        SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL );
                                        uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 );
                                        uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW );
                                        aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ),
                                            uno::makeAny( xSpreadsheetView ) );
                                        xJob->execute( aArgsForJob );
                                    }
                                }
                            }
                        }
                    }
                    catch ( uno::Exception & )
                    {
                    }
                }
                break;
            case SFX_EVENT_SAVEDOC:
                {
                    if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
                    {
                        bool bSuccess = false;
                        bool bRetry = true;
                        while ( bRetry )
                        {
                            bRetry = false;
                            uno::Reference< frame::XModel > xModel;
                            try
                            {
                                // load shared file
                                xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
                                uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );

                                // check if shared flag is set in shared file
                                bool bShared = false;
                                ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
                                ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : NULL );
                                if ( pSharedDocShell )
                                {
                                    bShared = pSharedDocShell->HasSharedXMLFlagSet();
                                }

                                // #i87870# check if shared status was disabled and enabled again
                                bool bOwnEntry = false;
                                bool bEntriesNotAccessible = false;
                                try
                                {
                                    ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
                                    bOwnEntry = aControlFile.HasOwnEntry();
                                }
                                catch ( uno::Exception& )
                                {
                                    bEntriesNotAccessible = true;
                                }

                                if ( bShared && bOwnEntry )
                                {
                                    uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );

                                    if ( xStorable->isReadonly() )
                                    {
                                        xCloseable->close( sal_True );

                                        String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
                                        bool bNoLockAccess = false;
                                        try
                                        {
                                            ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
                                            uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
                                            if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
                                            {
                                                if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
                                                {
                                                    aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
                                                }
                                                else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
                                                {
                                                    aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
                                                }
                                            }
                                        }
                                        catch ( uno::Exception& )
                                        {
                                            bNoLockAccess = true;
                                        }

                                        if ( bNoLockAccess )
                                        {
                                            // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
                                            ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
                                        }
                                        else
                                        {
                                            String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER ) );
                                            aMessage.SearchAndReplaceAscii( "%1", aUserName );

                                            WarningBox aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL | WB_DEF_RETRY ), aMessage );
                                            if ( aBox.Execute() == RET_RETRY )
                                            {
                                                bRetry = true;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // merge changes from shared file into temp file
                                        bool bSaveToShared = false;
                                        if ( pSharedDocShell )
                                        {
                                            bSaveToShared = MergeSharedDocument( pSharedDocShell );
                                        }

                                        // close shared file
                                        xCloseable->close( sal_True );

                                        // TODO: keep file lock on shared file

                                        // store to shared file
                                        if ( bSaveToShared )
                                        {
                                            bool bChangedViewSettings = false;
                                            ScChangeViewSettings* pChangeViewSet = aDocument.GetChangeViewSettings();
                                            if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
                                            {
                                                pChangeViewSet->SetShowChanges( sal_False );
                                                pChangeViewSet->SetShowAccepted( sal_False );
                                                aDocument.SetChangeViewSettings( *pChangeViewSet );
                                                bChangedViewSettings = true;
                                            }

                                            uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW );
                                            // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
                                            uno::Sequence< beans::PropertyValue > aValues(1);
                                            aValues[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
                                            aValues[0].Value <<= ::rtl::OUString( GetMedium()->GetFilter()->GetFilterName() );

                                            SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
                                            if ( pPasswordItem && pPasswordItem->GetValue().Len() )
                                            {
                                                aValues.realloc( 2 );
                                                aValues[1].Name = ::rtl::OUString::createFromAscii( "Password" );
                                                aValues[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
                                            }

                                            SC_MOD()->SetInSharedDocSaving( true );
                                            xStor->storeToURL( GetSharedFileURL(), aValues );
                                            SC_MOD()->SetInSharedDocSaving( false );

                                            if ( bChangedViewSettings )
                                            {
                                                pChangeViewSet->SetShowChanges( sal_True );
                                                pChangeViewSet->SetShowAccepted( sal_True );
                                                aDocument.SetChangeViewSettings( *pChangeViewSet );
                                            }
                                        }

                                        bSuccess = true;
                                        GetUndoManager()->Clear();
                                    }
                                }
                                else
                                {
                                    xCloseable->close( sal_True );

                                    if ( bEntriesNotAccessible )
                                    {
                                        // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
                                        ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
                                    }
                                    else
                                    {
                                        WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
                                            ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
                                        aBox.Execute();

                                        SfxBindings* pBindings = GetViewBindings();
                                        if ( pBindings )
                                        {
                                            pBindings->ExecuteSynchron( SID_SAVEASDOC );
                                        }
                                    }
                                }
                            }
                            catch ( uno::Exception& )
                            {
                                DBG_ERROR( "SFX_EVENT_SAVEDOC: caught exception\n" );
                                SC_MOD()->SetInSharedDocSaving( false );

                                try
                                {
                                    uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
                                    xClose->close( sal_True );
                                }
                                catch ( uno::Exception& )
                                {
                                }
                            }
                        }

                        if ( !bSuccess )
                            SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process
                    }
                    if (pSheetSaveData)
                        pSheetSaveData->SetInSupportedSave(true);
                }
                break;
            case SFX_EVENT_SAVEASDOC:
            case SFX_EVENT_SAVETODOC:
                // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
                // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
                // if there is a SAVE/SAVEAS/SAVETO event first.
                if (pSheetSaveData)
                    pSheetSaveData->SetInSupportedSave(true);
                break;
            case SFX_EVENT_SAVEDOCDONE:
                {
                    if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
                    {
                    }
                    UseSheetSaveEntries();      // use positions from saved file for next saving
                    if (pSheetSaveData)
                        pSheetSaveData->SetInSupportedSave(false);
                }
                break;
            case SFX_EVENT_SAVEASDOCDONE:
                // new positions are used after "save" and "save as", but not "save to"
                UseSheetSaveEntries();      // use positions from saved file for next saving
                if (pSheetSaveData)
                    pSheetSaveData->SetInSupportedSave(false);
                break;
            case SFX_EVENT_SAVETODOCDONE:
                // only reset the flag, don't use the new positions
                if (pSheetSaveData)
                    pSheetSaveData->SetInSupportedSave(false);
                break;
            default:
                {
                }
                break;
        }
    }
}

	// Inhalte fuer Organizer laden


sal_Bool __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium )
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" );

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

	WaitObject aWait( GetActiveDialogParent() );

	sal_Bool bRet = sal_False;

    if (GetMedium())
    {
        SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
        nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
    }

    //  until loading/saving only the styles in XML is implemented,
    //  load the whole file
    bRet = LoadXML( &rMedium, NULL );
    InitItems();

    SfxObjectShell::LoadFrom( rMedium );

	return bRet;
}

static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
{
    OUStringBuffer aBuf;
    OUString aTokens[2];
    sal_Int32 n = rOption.getLength();
    const sal_Unicode* p = rOption.getStr();
    sal_Int32 nTokenId = 0;
    for (sal_Int32 i = 0; i < n; ++i)
    {
        const sal_Unicode c = p[i];
        if (c == sal_Unicode(' '))
        {
            if (aBuf.getLength())
                aTokens[nTokenId++] = aBuf.makeStringAndClear();
        }
        else
            aBuf.append(c);

        if (nTokenId >= 2)
            break;
    }

    if (aBuf.getLength())
        aTokens[nTokenId] = aBuf.makeStringAndClear();

    rLang = static_cast<LanguageType>(aTokens[0].toInt32());
    rDateConvert = static_cast<bool>(aTokens[1].toInt32());
}

namespace {

class LoadMediumGuard
{
public:
    explicit LoadMediumGuard(ScDocument* pDoc) :
        mpDoc(pDoc)
    {
        mpDoc->SetLoadingMedium(true);
    }

    ~LoadMediumGuard()
    {
        mpDoc->SetLoadingMedium(false);
    }
private:
    ScDocument* mpDoc;
};

}

sal_Bool __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" );

    LoadMediumGuard aLoadGuard(&aDocument);

	sal_Bool bRet = sal_False;				// sal_False heisst Benutzerabbruch !!
									// bei Fehler: Fehler am Stream setzen!!

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

	GetUndoManager()->Clear();

	// ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
	sal_Bool bSetColWidths = sal_False;
	sal_Bool bSetSimpleTextColWidths = sal_False;
	sal_Bool bSimpleColWidth[MAXCOLCOUNT];
	memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(sal_Bool) );
	ScRange aColWidthRange;
	// ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
	sal_Bool bSetRowHeights = sal_False;

	aConvFilterName.Erase(); //@ #BugId 54198

	//	Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
	//	darum vorher per CreateFileStream dafuer sorgen, dass die komplette
	//	Datei uebertragen wird.
	rMedium.GetPhysicalName();	//! CreateFileStream direkt rufen, wenn verfuegbar

    SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
    nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;

    const SfxFilter* pFilter = rMedium.GetFilter();
	if (pFilter)
	{
		String aFltName = pFilter->GetFilterName();

		aConvFilterName=aFltName; //@ #BugId 54198

		sal_Bool bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) );
		sal_Bool bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) );
		if (!bCalc3 && !bCalc4)
			aDocument.SetInsertingFromOtherDoc( sal_True );

        if (aFltName.EqualsAscii(pFilterXML))
			bRet = LoadXML( &rMedium, NULL );
		else if (aFltName.EqualsAscii(pFilterSc10))
		{
			SvStream* pStream = rMedium.GetInStream();
			if (pStream)
			{
				FltError eError = ScFormatFilter::Get().ScImportStarCalc10( *pStream, &aDocument );
				if (eError != eERR_OK)
				{
					if (!GetError())
						SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
				}
				else
					bRet = sal_True;
			}
		}
		else if (aFltName.EqualsAscii(pFilterLotus))
		{
			String sItStr;
			SfxItemSet*	 pSet = rMedium.GetItemSet();
			const SfxPoolItem* pItem;
			if ( pSet && SFX_ITEM_SET ==
				 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
			{
				sItStr = ((const SfxStringItem*)pItem)->GetValue();
			}

			if (sItStr.Len() == 0)
			{
				//	default for lotus import (from API without options):
				//	IBM_437 encoding
				sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
			}

			ScColumn::bDoubleAlloc = sal_True;
			FltError eError = ScFormatFilter::Get().ScImportLotus123( rMedium, &aDocument,
												ScGlobal::GetCharsetValue(sItStr));
			ScColumn::bDoubleAlloc = sal_False;
			if (eError != eERR_OK)
			{
				if (!GetError())
					SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));

				if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
					bRet = sal_True;
			}
			else
				bRet = sal_True;
			bSetColWidths = sal_True;
			bSetRowHeights = sal_True;
		}
		else if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterExcel5) ||
				   aFltName.EqualsAscii(pFilterExcel95) || aFltName.EqualsAscii(pFilterExcel97) ||
				   aFltName.EqualsAscii(pFilterEx4Temp) || aFltName.EqualsAscii(pFilterEx5Temp) ||
				   aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) )
		{
			EXCIMPFORMAT eFormat = EIF_AUTO;
			if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterEx4Temp) )
				eFormat = EIF_BIFF_LE4;
			else if ( aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
					  aFltName.EqualsAscii(pFilterEx5Temp) || aFltName.EqualsAscii(pFilterEx95Temp) )
				eFormat = EIF_BIFF5;
			else if ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) )
				eFormat = EIF_BIFF8;

			MakeDrawLayer();				//! im Filter
            CalcOutputFactor();             // #93255# prepare update of row height
			ScColumn::bDoubleAlloc = sal_True;
			FltError eError = ScFormatFilter::Get().ScImportExcel( rMedium, &aDocument, eFormat );
			ScColumn::bDoubleAlloc = sal_False;
			aDocument.UpdateFontCharSet();
			if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
				aDocument.UpdateChartListenerCollection();				//! fuer alle Importe?

			// #75299# all graphics objects must have names
			aDocument.EnsureGraphicNames();

			if (eError == SCWARN_IMPORT_RANGE_OVERFLOW)
			{
				if (!GetError())
					SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
				bRet = sal_True;
			}
			else if (eError != eERR_OK)
			{
				if (!GetError())
					SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
			}
			else
				bRet = sal_True;

            // #93255# update of row height done inside of Excel filter to speed up chart import
//            bSetRowHeights = sal_True;      //  #75357# optimal row heights must be updated
		}
		else if (aFltName.EqualsAscii(pFilterAscii))
		{
			SfxItemSet*	 pSet = rMedium.GetItemSet();
			const SfxPoolItem* pItem;
			ScAsciiOptions aOptions;
			sal_Bool bOptInit = sal_False;

			if ( pSet && SFX_ITEM_SET ==
				 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
			{
				aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() );
				bOptInit = sal_True;
			}

			if ( !bOptInit )
			{
				//	default for ascii import (from API without options):
				//	ISO8859-1/MS_1252 encoding, comma, double quotes

				aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 );
				aOptions.SetFieldSeps( (sal_Unicode) ',' );
				aOptions.SetTextSep( (sal_Unicode) '"' );
			}

			FltError eError = eERR_OK;
			sal_Bool bOverflow = sal_False;

			if( ! rMedium.IsStorage() )
			{
				ScImportExport	aImpEx( &aDocument );
				aImpEx.SetExtOptions( aOptions );

				SvStream* pInStream = rMedium.GetInStream();
				if (pInStream)
				{
					pInStream->SetStreamCharSet( aOptions.GetCharSet() );
					pInStream->Seek( 0 );
                    bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL() );
					eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT;
					aDocument.StartAllListeners();
					aDocument.SetDirty();
					bOverflow = aImpEx.IsOverflow();
				}
				else
				{
					DBG_ERROR( "No Stream" );
				}
			}

			if (eError != eERR_OK)
			{
				if (!GetError())
					SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
			}
			else if ( bOverflow )
			{
				if (!GetError())
					SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
			}
			bSetColWidths = sal_True;
			bSetSimpleTextColWidths = sal_True;
		}
		else if (aFltName.EqualsAscii(pFilterDBase))
		{
			String sItStr;
			SfxItemSet*	 pSet = rMedium.GetItemSet();
			const SfxPoolItem* pItem;
			if ( pSet && SFX_ITEM_SET ==
				 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
			{
				sItStr = ((const SfxStringItem*)pItem)->GetValue();
			}

			if (sItStr.Len() == 0)
			{
				//	default for dBase import (from API without options):
				//	IBM_850 encoding

				sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
			}

			sal_uLong eError = DBaseImport( rMedium.GetPhysicalName(),
					ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );

			if (eError != eERR_OK)
			{
				if (!GetError())
					SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
				bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW );
			}
			else
				bRet = sal_True;

			aColWidthRange.aStart.SetRow( 1 );	// Spaltenheader nicht
			bSetColWidths = sal_True;
			bSetSimpleTextColWidths = sal_True;
			// Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
			for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
			{
				if ( !bSimpleColWidth[nCol] )
					bSetRowHeights = sal_True;
			}
		}
		else if (aFltName.EqualsAscii(pFilterDif))
		{
			SvStream* pStream = rMedium.GetInStream();
			if (pStream)
			{
				FltError eError;
				String sItStr;
				SfxItemSet*	 pSet = rMedium.GetItemSet();
				const SfxPoolItem* pItem;
				if ( pSet && SFX_ITEM_SET ==
					 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
				{
					sItStr = ((const SfxStringItem*)pItem)->GetValue();
				}

				if (sItStr.Len() == 0)
				{
					//	default for DIF import (from API without options):
					//	ISO8859-1/MS_1252 encoding

					sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
				}

				eError = ScFormatFilter::Get().ScImportDif( *pStream, &aDocument, ScAddress(0,0,0),
									ScGlobal::GetCharsetValue(sItStr));
				if (eError != eERR_OK)
				{
					if (!GetError())
						SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));

					if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
						bRet = sal_True;
				}
				else
					bRet = sal_True;
			}
			bSetColWidths = sal_True;
			bSetSimpleTextColWidths = sal_True;
			bSetRowHeights = sal_True;
		}
		else if (aFltName.EqualsAscii(pFilterSylk))
		{
			FltError eError = SCERR_IMPORT_UNKNOWN;
			if( !rMedium.IsStorage() )
			{
				ScImportExport aImpEx( &aDocument );

				SvStream* pInStream = rMedium.GetInStream();
				if (pInStream)
				{
					pInStream->Seek( 0 );
                    bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SOT_FORMATSTR_ID_SYLK );
					eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN;
					aDocument.StartAllListeners();
					aDocument.SetDirty();
				}
				else
				{
					DBG_ERROR( "No Stream" );
				}
			}

			if ( eError != eERR_OK && !GetError() )
				SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
			bSetColWidths = sal_True;
			bSetSimpleTextColWidths = sal_True;
			bSetRowHeights = sal_True;
		}
		else if (aFltName.EqualsAscii(pFilterQPro6))
        {
            ScColumn::bDoubleAlloc = sal_True;
            FltError eError = ScFormatFilter::Get().ScImportQuattroPro( rMedium, &aDocument);
            ScColumn::bDoubleAlloc = sal_False;
            if (eError != eERR_OK)
            {
                if (!GetError())
                    SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
                if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
                    bRet = sal_True;
            }
            else
                bRet = sal_True;
            // TODO: Filter should set column widths. Not doing it here, it may
            // result in very narrow or wide columns, depending on content.
            // Setting row heights makes cells with font size attribution or
            // wrapping enabled look nicer..
            bSetRowHeights = sal_True;
        }
		else if (aFltName.EqualsAscii(pFilterRtf))
		{
			FltError eError = SCERR_IMPORT_UNKNOWN;
			if( !rMedium.IsStorage() )
			{
				SvStream* pInStream = rMedium.GetInStream();
				if (pInStream)
				{
					pInStream->Seek( 0 );
					ScRange aRange;
                    eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange );
					if (eError != eERR_OK)
					{
						if (!GetError())
							SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));

						if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
							bRet = sal_True;
					}
					else
						bRet = sal_True;
					aDocument.StartAllListeners();
					aDocument.SetDirty();
					bSetColWidths = sal_True;
					bSetRowHeights = sal_True;
				}
				else
				{
					DBG_ERROR( "No Stream" );
				}
			}

			if ( eError != eERR_OK && !GetError() )
				SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
		}
		else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ))
		{
			FltError eError = SCERR_IMPORT_UNKNOWN;
			sal_Bool bWebQuery = aFltName.EqualsAscii(pFilterHtmlWebQ);
			if( !rMedium.IsStorage() )
			{
				SvStream* pInStream = rMedium.GetInStream();
				if (pInStream)
				{
                    LanguageType eLang = LANGUAGE_SYSTEM;
                    bool bDateConvert = false;
                    SfxItemSet*	 pSet = rMedium.GetItemSet();
                    const SfxPoolItem* pItem;
                    if ( pSet && SFX_ITEM_SET ==
                         pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
                    {
                        String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue();
                        lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
                    }

					pInStream->Seek( 0 );
					ScRange aRange;
					// HTML macht eigenes ColWidth/RowHeight
					CalcOutputFactor();
                    SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang);
                    eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange,
											GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert );
					if (eError != eERR_OK)
					{
						if (!GetError())
							SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));

						if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
							bRet = sal_True;
					}
					else
						bRet = sal_True;
					aDocument.StartAllListeners();
					aDocument.SetDirty();
				}
				else
				{
					DBG_ERROR( "No Stream" );
				}
			}

			if ( eError != eERR_OK && !GetError() )
				SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
		}
		else
		{
			if (!GetError())
				SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
		}

		if (!bCalc3)
			aDocument.SetInsertingFromOtherDoc( sal_False );
	}
	else
	{
		DBG_ERROR("Kein Filter bei ConvertFrom");
	}

	InitItems();
	CalcOutputFactor();
	if ( bRet && (bSetColWidths || bSetRowHeights) )
	{	// Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom
		Fraction aZoom( 1, 1 );
		double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
			/ GetOutputFactor();	// Faktor ist Drucker zu Bildschirm
		double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
		VirtualDevice aVirtDev;
		//	all sheets (for Excel import)
		SCTAB nTabCount = aDocument.GetTableCount();
		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
		{
            SCCOL nEndCol;
            SCROW nEndRow;
            aDocument.GetCellArea( nTab, nEndCol, nEndRow );
			aColWidthRange.aEnd.SetCol( nEndCol );
			aColWidthRange.aEnd.SetRow( nEndRow );
			ScMarkData aMark;
			aMark.SetMarkArea( aColWidthRange );
			aMark.MarkToMulti();
			// Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf)
			if ( bSetColWidths )
			{
				for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
				{
					sal_uInt16 nWidth = aDocument.GetOptimalColWidth(
						nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, sal_False, &aMark,
						(bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
					aDocument.SetColWidth( nCol, nTab,
						nWidth + (sal_uInt16)ScGlobal::nLastColWidthExtra );
				}
			}
//			if ( bSetRowHeights )
//			{
//				//	nExtra must be 0
//				aDocument.SetOptimalHeight(	0, nEndRow, nTab, 0, &aVirtDev,
//					nPPTX, nPPTY, aZoom, aZoom, sal_False );
//			}
		}
		if ( bSetRowHeights )
			UpdateAllRowHeights();		// with vdev or printer, depending on configuration
	}
	FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );

	GetUndoManager()->Clear();
	// #73762# invalidate eventually temporary table areas
	if ( bRet )
		aDocument.InvalidateTableArea();

	bIsEmpty = sal_False;

	return bRet;
}


ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
    : mrDocShell( rDocShell)
{
    // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.

    ScChartListenerCollection* pCharts = mrDocShell.aDocument.GetChartListenerCollection();
    if (pCharts)
        pCharts->UpdateDirtyCharts();                           // Charts to be updated.
    mrDocShell.aDocument.StopTemporaryChartLock();
    if (mrDocShell.pAutoStyleList)
        mrDocShell.pAutoStyleList->ExecuteAllNow();             // Execute template timeouts now.
    if (mrDocShell.aDocument.HasExternalRefManager())
    {
        ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
        if (pRefMgr && pRefMgr->hasExternalData())
        {
            pRefMgr->setAllCacheTableReferencedStati( false);
            mrDocShell.aDocument.MarkUsedExternalReferences();  // Mark tables of external references to be written.
        }
    }
    if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD)
        mrDocShell.SfxObjectShell::SetVisArea( Rectangle() );   // "Normally" worked on => no VisArea.
}

ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
{
    if (mrDocShell.aDocument.HasExternalRefManager())
    {
        ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
        if (pRefMgr && pRefMgr->hasExternalData())
        {
            // Prevent accidental data loss due to lack of knowledge.
            pRefMgr->setAllCacheTableReferencedStati( true);
        }
    }
}


sal_Bool __EXPORT ScDocShell::Save()
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" );

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

    PrepareSaveGuard aPrepareGuard( *this);

	//	wait cursor is handled with progress bar
    sal_Bool bRet = SfxObjectShell::Save();
	if( bRet )
        bRet = SaveXML( GetMedium(), NULL );
	return bRet;
}


sal_Bool __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" );

#if ENABLE_SHEET_PROTECTION
    ScTabViewShell* pViewShell = GetBestViewShell();
    if (pViewShell && ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_OOO))
    {
        if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_OOO))
            // password re-type cancelled.  Don't save the document.
            return false;
    }
#endif

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

    PrepareSaveGuard aPrepareGuard( *this);

	//	wait cursor is handled with progress bar
    sal_Bool bRet = SfxObjectShell::SaveAs( rMedium );
	if( bRet )
        bRet = SaveXML( &rMedium, NULL );

	return bRet;
}


sal_Bool __EXPORT ScDocShell::IsInformationLost()
{
/*
	const SfxFilter *pFilt = GetMedium()->GetFilter();
	sal_Bool bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost;
	if (bNoInformLost)					// nur einmal!!
		bNoInformLost = sal_False;
	return bRet;
*/
	//!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen

	return SfxObjectShell::IsInformationLost();
}


// Xcl-like column width measured in characters of standard font.
xub_StrLen lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth )
{
    // double fColScale = 1.0;
	double	f = nWidth;
	f *= 1328.0 / 25.0;
	f += 90.0;
	f *= 1.0 / 23.0;
	// f /= fColScale * 256.0;
	f /= 256.0;

	return xub_StrLen( f );
}


void lcl_ScDocShell_GetFixedWidthString( String& rStr, const ScDocument& rDoc,
        SCTAB nTab, SCCOL nCol, sal_Bool bValue, SvxCellHorJustify eHorJust )
{
    xub_StrLen nLen = lcl_ScDocShell_GetColWidthInChars(
            rDoc.GetColWidth( nCol, nTab ) );
    if ( nLen < rStr.Len() )
    {
        if ( bValue )
            rStr.AssignAscii( "###" );
        rStr.Erase( nLen );
    }
    if ( nLen > rStr.Len() )
    {
        if ( bValue && eHorJust == SVX_HOR_JUSTIFY_STANDARD )
            eHorJust = SVX_HOR_JUSTIFY_RIGHT;
        switch ( eHorJust )
        {
            case SVX_HOR_JUSTIFY_RIGHT:
            {
                String aTmp;
                aTmp.Fill( nLen - rStr.Len() );
                rStr.Insert( aTmp, 0 );
            }
            break;
            case SVX_HOR_JUSTIFY_CENTER:
            {
                xub_StrLen nLen2 = (nLen - rStr.Len()) / 2;
                String aTmp;
                aTmp.Fill( nLen2 );
                rStr.Insert( aTmp, 0 );
                rStr.Expand( nLen );
            }
            break;
            default:
                rStr.Expand( nLen );
        }
    }
}


void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
        const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
{
    String aString;
    lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, sal_False,
            SVX_HOR_JUSTIFY_STANDARD );
    rStream.WriteUnicodeOrByteText( aString );
}


void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt )
{
    sal_Unicode cDelim    = rAsciiOpt.nFieldSepCode;
    sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
    CharSet eCharSet      = rAsciiOpt.eCharSet;
    sal_Bool bFixedWidth      = rAsciiOpt.bFixedWidth;
    sal_Bool bSaveAsShown     = rAsciiOpt.bSaveAsShown;

	CharSet eOldCharSet = rStream.GetStreamCharSet();
	rStream.SetStreamCharSet( eCharSet );
	sal_uInt16 nOldNumberFormatInt = rStream.GetNumberFormatInt();
    ByteString aStrDelimEncoded;    // only used if not Unicode
    UniString aStrDelimDecoded;     // only used if context encoding
    ByteString aDelimEncoded;
    UniString aDelimDecoded;
    sal_Bool bContextOrNotAsciiEncoding;
	if ( eCharSet == RTL_TEXTENCODING_UNICODE )
    {
		rStream.StartWritingUnicodeText();
        bContextOrNotAsciiEncoding = sal_False;
    }
    else
    {
        aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
        aDelimEncoded = ByteString( cDelim, eCharSet );
        rtl_TextEncodingInfo aInfo;
        aInfo.StructSize = sizeof(aInfo);
        if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
        {
            bContextOrNotAsciiEncoding =
                (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
                 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
            if ( bContextOrNotAsciiEncoding )
            {
                aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
                aDelimDecoded = String( aDelimEncoded, eCharSet );
            }
        }
        else
            bContextOrNotAsciiEncoding = sal_False;
    }

	SCCOL nStartCol = 0;
	SCROW nStartRow = 0;
	SCTAB nTab = GetSaveTab();
	SCCOL nEndCol;
	SCROW nEndRow;
	aDocument.GetCellArea( nTab, nEndCol, nEndRow );

	ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow );

	String aString;

	ScTabViewShell*	pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
	const ScViewOptions& rOpt = (pViewSh)
								? pViewSh->GetViewData()->GetOptions()
								: aDocument.GetViewOptions();
	sal_Bool bShowFormulas = rOpt.GetOption( VOPT_FORMULAS );
	sal_Bool bTabProtect = aDocument.IsTabProtected( nTab );

	SCCOL nCol;
	SCROW nRow;
	SCCOL nNextCol = nStartCol;
	SCROW nNextRow = nStartRow;
	SCCOL nEmptyCol;
	SCROW nEmptyRow;
	SvNumberFormatter& rFormatter = *aDocument.GetFormatTable();

	ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow,
		nEndCol, nEndRow );
	ScBaseCell* pCell;
    while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != NULL )
    {
        sal_Bool bProgress = sal_False;		// only upon line change
        if ( nNextRow < nRow )
        {   // empty rows or/and empty columns up to end of row
            bProgress = sal_True;
            for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
            {   // remaining columns of last row
                if ( bFixedWidth )
                    lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                            aDocument, nTab, nEmptyCol );
                else if ( cDelim != 0 )
                    rStream.WriteUniOrByteChar( cDelim );
            }
            endlub( rStream );
            nNextRow++;
            for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
            {   // completely empty rows
                for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
                {
                    if ( bFixedWidth )
                        lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                                aDocument, nTab, nEmptyCol );
                    else if ( cDelim != 0 )
                        rStream.WriteUniOrByteChar( cDelim );
                }
                endlub( rStream );
            }
            for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
            {   // empty columns at beginning of row
                if ( bFixedWidth )
                    lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                            aDocument, nTab, nEmptyCol );
                else if ( cDelim != 0 )
                    rStream.WriteUniOrByteChar( cDelim );
            }
            nNextRow = nRow;
        }
        else if ( nNextCol < nCol )
        {   // empty columns in same row
            for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
            {   // columns in between
                if ( bFixedWidth )
                    lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                            aDocument, nTab, nEmptyCol );
                else if ( cDelim != 0 )
                    rStream.WriteUniOrByteChar( cDelim );
            }
        }
        if ( nCol == nEndCol )
        {
            bProgress = sal_True;
            nNextCol = nStartCol;
            nNextRow = nRow + 1;
        }
        else
            nNextCol = nCol + 1;

        CellType eType = pCell->GetCellType();
        if ( bTabProtect )
        {
            const ScProtectionAttr* pProtAttr =
                (const ScProtectionAttr*) aDocument.GetAttr(
                                                            nCol, nRow, nTab, ATTR_PROTECTION );
            if ( pProtAttr->GetHideCell() ||
                    ( eType == CELLTYPE_FORMULA && bShowFormulas &&
                      pProtAttr->GetHideFormula() ) )
                eType = CELLTYPE_NONE;	// hide
        }
        sal_Bool bString;
        switch ( eType )
        {
            case CELLTYPE_NOTE:
            case CELLTYPE_NONE:
                aString.Erase();
                bString = sal_False;
                break;
            case CELLTYPE_FORMULA :
                {
                    sal_uInt16 nErrCode;
                    if ( bShowFormulas )
                    {
                        ((ScFormulaCell*)pCell)->GetFormula( aString );
                        bString = sal_True;
                    }
                    else if ( ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) != 0 )
                    {
                        aString = ScGlobal::GetErrorString( nErrCode );
                        bString = sal_True;
                    }
                    else if ( ((ScFormulaCell*)pCell)->IsValue() )
                    {
                        sal_uInt32 nFormat;
                        aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
                        if ( bFixedWidth || bSaveAsShown )
                        {
                            Color* pDummy;
                            ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
                            bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
                        }
                        else
                        {
                            ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
                            bString = sal_False;
                        }
                    }
                    else
                    {
                        if ( bSaveAsShown )
                        {
                            sal_uInt32 nFormat;
                            aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
                            Color* pDummy;
                            ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
                        }
                        else
                            ((ScFormulaCell*)pCell)->GetString( aString );
                        bString = sal_True;
                    }
                }
                break;
            case CELLTYPE_STRING :
                if ( bSaveAsShown )
                {
                    sal_uInt32 nFormat;
                    aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
                    Color* pDummy;
                    ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
                }
                else
                    ((ScStringCell*)pCell)->GetString( aString );
                bString = sal_True;
                break;
            case CELLTYPE_EDIT :
                {
                    const EditTextObject* pObj;
                    static_cast<const ScEditCell*>(pCell)->GetData( pObj);
                    EditEngine& rEngine = aDocument.GetEditEngine();
                    rEngine.SetText( *pObj);
                    aString = rEngine.GetText();  // including LF
                    bString = sal_True;
                }
                break;
            case CELLTYPE_VALUE :
                {
                    sal_uInt32 nFormat;
                    aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
                    if ( bFixedWidth || bSaveAsShown )
                    {
                        Color* pDummy;
                        ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
                        bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
                    }
                    else
                    {
                        ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
                        bString = sal_False;
                    }
                }
                break;
            default:
                DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" );
                aString.Erase();
                bString = sal_False;
        }

        if ( bFixedWidth )
        {
            SvxCellHorJustify eHorJust = (SvxCellHorJustify)
                ((const SvxHorJustifyItem*) aDocument.GetAttr( nCol, nRow,
                nTab, ATTR_HOR_JUSTIFY ))->GetValue();
            lcl_ScDocShell_GetFixedWidthString( aString, aDocument, nTab, nCol,
                    !bString, eHorJust );
            rStream.WriteUnicodeOrByteText( aString );
        }
        else
        {
            if (!bString && cStrDelim != 0 && aString.Len() > 0)
            {
                sal_Unicode c = aString.GetChar(0);
                bString = (c == cStrDelim || c == ' ' ||
                        aString.GetChar( aString.Len()-1) == ' ' ||
                        aString.Search( cStrDelim) != STRING_NOTFOUND);
                if (!bString && cDelim != 0)
                    bString = (aString.Search( cDelim) != STRING_NOTFOUND);
            }
            if ( bString )
            {
                if ( cStrDelim != 0 ) //@ BugId 55355
                {
                    if ( eCharSet == RTL_TEXTENCODING_UNICODE )
                    {
                        xub_StrLen nPos = aString.Search( cStrDelim );
                        // #i116636# quotes are needed if text delimiter (quote), field delimiter, or LF is in the cell text
                        bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
                                            ( nPos != STRING_NOTFOUND ) ||
                                            ( aString.Search( cDelim ) != STRING_NOTFOUND ) ||
                                            ( aString.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND );
                        while ( nPos != STRING_NOTFOUND )
                        {
                            aString.Insert( cStrDelim, nPos );
                            nPos = aString.Search( cStrDelim, nPos+2 );
                        }
                        if ( bNeedQuotes )
                            rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
                        rStream.WriteUnicodeText( aString );
                        if ( bNeedQuotes )
                            rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
                    }
                    else
                    {
                        // #105549# This is nasty. The Unicode to byte encoding
                        // may convert typographical quotation marks to ASCII
                        // quotation marks, which may interfer with the delimiter,
                        // so we have to escape delimiters after the string has
                        // been encoded. Since this may happen also with UTF-8
                        // encoded typographical quotation marks if such was
                        // specified as a delimiter we have to check for the full
                        // encoded delimiter string, not just one character.
                        // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
                        // dead encodings where one code point (and especially a
                        // low ASCII value) may represent different characters, we
                        // have to convert forth and back and forth again. Same for
                        // UTF-7 since it is a context sensitive encoding too.

                        if ( bContextOrNotAsciiEncoding )
                        {
                            // to byte encoding
                            ByteString aStrEnc( aString, eCharSet );
                            // back to Unicode
                            UniString aStrDec( aStrEnc, eCharSet );
                            // search on re-decoded string
                            xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
                            bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
                                                ( nPos != STRING_NOTFOUND ) ||
                                                ( aStrDec.Search( aDelimDecoded ) != STRING_NOTFOUND ) ||
                                                ( aStrDec.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND );
                            while ( nPos != STRING_NOTFOUND )
                            {
                                aStrDec.Insert( aStrDelimDecoded, nPos );
                                nPos = aStrDec.Search( aStrDelimDecoded,
                                        nPos+1+aStrDelimDecoded.Len() );
                            }
                            // write byte re-encoded
                            if ( bNeedQuotes )
                                rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
                            rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
                            if ( bNeedQuotes )
                                rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
                        }
                        else
                        {
                            ByteString aStrEnc( aString, eCharSet );
                            // search on encoded string
                            xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
                            bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
                                                ( nPos != STRING_NOTFOUND ) ||
                                                ( aStrEnc.Search( aDelimEncoded ) != STRING_NOTFOUND ) ||
                                                ( aStrEnc.Search( sal_Char(_LF) ) != STRING_NOTFOUND );
                            while ( nPos != STRING_NOTFOUND )
                            {
                                aStrEnc.Insert( aStrDelimEncoded, nPos );
                                nPos = aStrEnc.Search( aStrDelimEncoded,
                                        nPos+1+aStrDelimEncoded.Len() );
                            }
                            // write byte encoded
                            if ( bNeedQuotes )
                                rStream.Write( aStrDelimEncoded.GetBuffer(),
                                        aStrDelimEncoded.Len() );
                            rStream.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
                            if ( bNeedQuotes )
                                rStream.Write( aStrDelimEncoded.GetBuffer(),
                                        aStrDelimEncoded.Len() );
                        }
                    }
                }
                else
                    rStream.WriteUnicodeOrByteText( aString );
            }
            else
                rStream.WriteUnicodeOrByteText( aString );
        }

        if( nCol < nEndCol )
        {
            if(cDelim!=0) //@ BugId 55355
                rStream.WriteUniOrByteChar( cDelim );
        }
        else
            endlub( rStream );

        if ( bProgress )
            aProgress.SetStateOnPercent( nRow );
    }

	// write out empty if requested
	if ( nNextRow <= nEndRow )
	{
        for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
        {	// remaining empty columns of last row
            if ( bFixedWidth )
                lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                        aDocument, nTab, nEmptyCol );
            else if ( cDelim != 0 )
                rStream.WriteUniOrByteChar( cDelim );
        }
		endlub( rStream );
		nNextRow++;
	}
	for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ )
	{	// entire empty rows
        for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
        {
            if ( bFixedWidth )
                lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
                        aDocument, nTab, nEmptyCol );
            else if ( cDelim != 0 )
                rStream.WriteUniOrByteChar( cDelim );
        }
		endlub( rStream );
	}

	rStream.SetStreamCharSet( eOldCharSet );
	rStream.SetNumberFormatInt( nOldNumberFormatInt );
}

sal_Bool __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );

	ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

    //  #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
    //  it's already in ExecuteSave (as for Save and SaveAs)

	if (pAutoStyleList)
		pAutoStyleList->ExecuteAllNow();				// Vorlagen-Timeouts jetzt ausfuehren
	if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
        SfxObjectShell::SetVisArea( Rectangle() );     // normal bearbeitet -> keine VisArea

	DBG_ASSERT( rMed.GetFilter(), "Filter == 0" );

	sal_Bool bRet = sal_False;
	String aFltName = rMed.GetFilter()->GetFilterName();

/*
	if (aFltName.EqualsAscii(pFilterLotus))
	{
		SvStream* pStream = rMed.GetOutStream();
		if (pStream)
		{
			FltError eError = ScFormatFilter::Get().ScExportLotus123( *pStream, &aDocument, ExpWK1,
												CHARSET_IBMPC_437 );
			bRet = eError == eERR_OK;
		}
	}
	else
*/
    if (aFltName.EqualsAscii(pFilterXML))
	{
        //TODO/LATER: this shouldn't happen!
        DBG_ERROR("XML filter in ConvertFrom?!");
		bRet = SaveXML( &rMed, NULL );
	}
	else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
			 aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) ||
			 aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ||
			 aFltName.EqualsAscii(pFilterEx07Xml))
	{
		WaitObject aWait( GetActiveDialogParent() );

        bool bDoSave = true;
        if( ScTabViewShell* pViewShell = GetBestViewShell() )
        {
            ScExtDocOptions* pExtDocOpt = aDocument.GetExtDocOptions();
            if( !pExtDocOpt )
                aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
            pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );

            /*  #115980# #i104990# If the imported document contains a medium
                password, determine if we can save it, otherwise ask the users
                whether they want to save without it. */
            if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 )
            {
                SfxItemSet* pItemSet = rMed.GetItemSet();
                const SfxPoolItem* pItem = 0;
                if( pItemSet && pItemSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) == SFX_ITEM_SET )
                {
                    bDoSave = ScWarnPassword::WarningOnPassword( rMed );
                    // #i42858# remove password from medium (warn only one time)
                    if( bDoSave )
                        pItemSet->ClearItem( SID_PASSWORD );
                }
            }

#if ENABLE_SHEET_PROTECTION
            if( bDoSave )
            {
                bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( aDocument, PASSHASH_XL );
                bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL );
            }
#endif
        }

        if( bDoSave )
        {
            ExportFormatExcel eFormat = ExpBiff5;
            if( aFltName.EqualsAscii( pFilterExcel97 ) || aFltName.EqualsAscii( pFilterEx97Temp ) )
                eFormat = ExpBiff8;
            if( aFltName.EqualsAscii( pFilterEx07Xml ) )
                eFormat = Exp2007Xml;
            FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 );

            if( eError && !GetError() )
                SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );

            // don't return false for warnings
            bRet = ((eError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK) || (eError == eERR_OK);
        }
        else
        {
            // export aborted, i.e. "Save without password" warning
            SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
        }
    }
	else if (aFltName.EqualsAscii(pFilterAscii))
	{
		SvStream* pStream = rMed.GetOutStream();
		if (pStream)
		{
			String sItStr;
			SfxItemSet*	 pSet = rMed.GetItemSet();
			const SfxPoolItem* pItem;
			if ( pSet && SFX_ITEM_SET ==
				 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
			{
				sItStr = ((const SfxStringItem*)pItem)->GetValue();
			}

			if ( sItStr.Len() == 0 )
			{
				//	default for ascii export (from API without options):
				//	ISO8859-1/MS_1252 encoding, comma, double quotes

				ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
				sItStr = aDefOptions.BuildString();
			}

			WaitObject aWait( GetActiveDialogParent() );
			ScImportOptions aOptions( sItStr );
			AsciiSave( *pStream, aOptions );
			bRet = sal_True;

			if (aDocument.GetTableCount() > 1)
				if (!rMed.GetError())
					rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
		}
	}
	else if (aFltName.EqualsAscii(pFilterDBase))
	{
		String sCharSet;
		SfxItemSet*	pSet = rMed.GetItemSet();
		const SfxPoolItem* pItem;
		if ( pSet && SFX_ITEM_SET ==
			 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
		{
			sCharSet = ((const SfxStringItem*)pItem)->GetValue();
		}

		if (sCharSet.Len() == 0)
		{
			//	default for dBase export (from API without options):
			//	IBM_850 encoding

			sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
		}

		WaitObject aWait( GetActiveDialogParent() );
// HACK damit Sba geoffnetes TempFile ueberschreiben kann
		rMed.CloseOutStream();
		sal_Bool bHasMemo = sal_False;

		sal_uLong eError = DBaseExport( rMed.GetPhysicalName(),
						ScGlobal::GetCharsetValue(sCharSet), bHasMemo );

		if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) )
		{
//!			if ( !rMed.GetError() )
//!				rMed.SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
			eError = eERR_OK;
		}
//!		else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() )
//!			rMed.SetError( SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );

		INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE );
		if ( bHasMemo )
			aTmpFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
		if ( eError != eERR_OK )
		{
			if (!GetError())
				SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
			if ( bHasMemo && IsDocument( aTmpFile ) )
				KillFile( aTmpFile );
		}
		else
		{
			bRet = sal_True;
			if ( bHasMemo )
			{
				SfxStringItem* pNameItem =
					(SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME );
				INetURLObject aDbtFile( pNameItem->GetValue(), INET_PROT_FILE );
				aDbtFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
				if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
					bRet = sal_False;
				if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
					bRet = sal_False;
				if ( !bRet )
				{
					KillFile( aTmpFile );
					if ( !GetError() )
						SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
				}
			}
		}
	}
	else if (aFltName.EqualsAscii(pFilterDif))
	{
		SvStream* pStream = rMed.GetOutStream();
		if (pStream)
		{
			String sItStr;
			SfxItemSet*	 pSet = rMed.GetItemSet();
			const SfxPoolItem* pItem;
			if ( pSet && SFX_ITEM_SET ==
				 pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
			{
				sItStr = ((const SfxStringItem*)pItem)->GetValue();
			}

			if (sItStr.Len() == 0)
			{
				//	default for DIF export (from API without options):
				//	ISO8859-1/MS_1252 encoding

				sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
			}

			WaitObject aWait( GetActiveDialogParent() );
			ScFormatFilter::Get().ScExportDif( *pStream, &aDocument, ScAddress(0,0,0),
				ScGlobal::GetCharsetValue(sItStr) );
			bRet = sal_True;

			if (aDocument.GetTableCount() > 1)
				if (!rMed.GetError())
					rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
		}
	}
	else if (aFltName.EqualsAscii(pFilterSylk))
	{
		SvStream* pStream = rMed.GetOutStream();
		if ( pStream )
		{
			WaitObject aWait( GetActiveDialogParent() );

            SCCOL nEndCol;
            SCROW nEndRow;
            aDocument.GetCellArea( 0, nEndCol, nEndRow );
			ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );

			ScImportExport aImExport( &aDocument, aRange );
            aImExport.SetFormulas( sal_True );
            bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK );
		}
	}
	else if (aFltName.EqualsAscii(pFilterHtml))
	{
		SvStream* pStream = rMed.GetOutStream();
		if ( pStream )
		{
            WaitObject aWait( GetActiveDialogParent() );
			ScImportExport aImExport( &aDocument );
			aImExport.SetStreamPath( rMed.GetName() );
            bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML );
            if ( bRet && aImExport.GetNonConvertibleChars().Len() )
                SetError( *new StringErrorInfo(
                    SCWARN_EXPORT_NONCONVERTIBLE_CHARS,
                    aImExport.GetNonConvertibleChars(),
                    ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
		}
	}
	else
	{
		if (GetError())
			SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
	}
	return bRet;
}


sal_Bool __EXPORT ScDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
{
    return SfxObjectShell::SaveCompleted( xStor );
}


sal_Bool __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor )
{
	sal_Bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor );

	//	SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write
	Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) );
	return bRet;
}


sal_Bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId )
{
    // #i112634# ask VBA event handlers whether to save or print the document
    
    using namespace ::com::sun::star::script::vba;

    sal_Int32 nVbaEventId = VBAEventId::NO_EVENT;
    uno::Sequence< uno::Any > aArgs;
    switch( nSlotId )
    {
        case SID_SAVEDOC:
        case SID_SAVEASDOC:
            nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE;
            aArgs.realloc( 1 );
            aArgs[ 0 ] <<= (nSlotId == SID_SAVEASDOC);
        break;
        case SID_PRINTDOC:
        case SID_PRINTDOCDIRECT:
            nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT;
        break;
    }

    sal_Bool bSlotExecutable = sal_True;
    if( nVbaEventId != VBAEventId::NO_EVENT ) try
    {
        uno::Reference< XVBAEventProcessor > xEventProcessor( aDocument.GetVbaEventProcessor(), uno::UNO_QUERY_THROW );
        xEventProcessor->processVbaEvent( nVbaEventId, aArgs );
    }
    catch( util::VetoException& )
    {
        bSlotExecutable = sal_False;
    }
    catch( uno::Exception& )
    {
    }
    return bSlotExecutable;
}


sal_uInt16 __EXPORT ScDocShell::PrepareClose( sal_Bool bUI, sal_Bool bForBrowsing )
{
	if(SC_MOD()->GetCurRefDlgId()>0)
	{
		SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
		if( pFrame )
		{
			SfxViewShell* p = pFrame->GetViewShell();
			ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
			if(pViewSh!=NULL)
			{
				Window *pWin=pViewSh->GetWindow();
				if(pWin!=NULL) pWin->GrabFocus();
			}
		}

		return sal_False;
	}
	if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() )
	{
		ErrorMessage(STR_CLOSE_ERROR_LINK);
		return sal_False;
	}

	DoEnterHandler();

	// start 'Workbook_BeforeClose' VBA event handler for possible veto
    if( !IsInPrepareClose() )
    {
        try
        {
            uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( aDocument.GetVbaEventProcessor(), uno::UNO_SET_THROW );
            uno::Sequence< uno::Any > aArgs;
            xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs );
        }
        catch( util::VetoException& )
        {
            // if event processor throws VetoException, macro has vetoed close
		    return sal_False;
		}
        catch( uno::Exception& )
        {
        }
    }
	// end handler code

	sal_uInt16 nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing );
	if (nRet == sal_True)						// sal_True = schliessen
		aDocument.DisableIdle(sal_True);		// nicht mehr drin rumpfuschen !!!

	return nRet;
}

void ScDocShell::PrepareReload()
{
	SfxObjectShell::PrepareReload();	// tut nichts?

	//	Das Disconnect von DDE-Links kann Reschedule ausloesen.
	//	Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload
	//	aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest
	//	werden. Dabei verklemmt sicht dann irgendwas.
	//	-> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten

	aDocument.DisconnectDdeLinks();
}


String ScDocShell::GetOwnFilterName()			// static
{
	return String::CreateFromAscii(pFilterSc50);
}

String ScDocShell::GetHtmlFilterName()
{
    return String::CreateFromAscii(pFilterHtml);
}

String ScDocShell::GetWebQueryFilterName()		// static
{
	return String::CreateFromAscii(pFilterHtmlWebQ);
}

String ScDocShell::GetAsciiFilterName()			// static
{
	return String::CreateFromAscii(pFilterAscii);
}

String ScDocShell::GetLotusFilterName()			// static
{
	return String::CreateFromAscii(pFilterLotus);
}

String ScDocShell::GetDBaseFilterName()			// static
{
	return String::CreateFromAscii(pFilterDBase);
}

String ScDocShell::GetDifFilterName()			// static
{
	return String::CreateFromAscii(pFilterDif);
}

sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter )		// static
{
	//	sal_True for those filters that keep the default table name
	//	(which is language specific)

	return rFilter.EqualsAscii( pFilterAscii )
		|| rFilter.EqualsAscii( pFilterLotus )
		|| rFilter.EqualsAscii( pFilterExcel4 )
		|| rFilter.EqualsAscii( pFilterEx4Temp )
		|| rFilter.EqualsAscii( pFilterDBase )
		|| rFilter.EqualsAscii( pFilterDif )
		|| rFilter.EqualsAscii( pFilterSylk )
		|| rFilter.EqualsAscii( pFilterHtml )
		|| rFilter.EqualsAscii( pFilterRtf );
}

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

#define __SCDOCSHELL_INIT \
		aDocument		( SCDOCMODE_DOCUMENT, this ), \
        aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), \
		nPrtToScreenFactor( 1.0 ), \
        pImpl           ( new DocShell_Impl ), \
		bHeaderOn		( sal_True ), \
		bFooterOn		( sal_True ), \
        bNoInformLost   ( sal_True ), \
		bIsEmpty		( sal_True ), \
		bIsInUndo		( sal_False ), \
		bDocumentModifiedPending( sal_False ), \
		nDocumentLock	( 0 ), \
        nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG), \
        bUpdateEnabled  ( sal_True ), \
        pOldAutoDBRange ( NULL ), \
		pDocHelper 		( NULL ), \
		pAutoStyleList	( NULL ), \
		pPaintLockData	( NULL ), \
		pOldJobSetup	( NULL ), \
        pSolverSaveData ( NULL ), \
        pSheetSaveData  ( NULL ), \
        pModificator    ( NULL )

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

ScDocShell::ScDocShell( const ScDocShell& rShell )
    :   SvRefBase(),
        SotObject(),
	    SfxObjectShell( rShell.GetCreateMode() ),
        SfxListener(),
		__SCDOCSHELL_INIT
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );

	SetPool( &SC_MOD()->GetPool() );

	bIsInplace = rShell.bIsInplace;

	pDocFunc = new ScDocFunc(*this);

	//	SetBaseModel needs exception handling
	ScModelObj::CreateAndSet( this );

	StartListening(*this);
	SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
	if (pStlPool)
		StartListening(*pStlPool);

	GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn );
	SetHelpId( HID_SCSHELL_DOCSH );

	//	InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
}

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

ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags )
	:	SfxObjectShell( i_nSfxCreationFlags )
    ,   __SCDOCSHELL_INIT
{
	RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );

	SetPool( &SC_MOD()->GetPool() );

	bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
	//	wird zurueckgesetzt, wenn nicht inplace

    // #118840# set flag at ScDocument that it is used temporary (e.g. inplace 
    // for transporting a chart over the clipboard)
    if(bIsInplace)
    {
        aDocument.mbIsTemporary = true;
    }

	pDocFunc = new ScDocFunc(*this);

	//	SetBaseModel needs exception handling
	ScModelObj::CreateAndSet( this );

	StartListening(*this);
	SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
	if (pStlPool)
		StartListening(*pStlPool);
	SetHelpId( HID_SCSHELL_DOCSH );

	aDocument.GetDBCollection()->SetRefreshHandler(
		LINK( this, ScDocShell, RefreshDBDataHdl ) );

	//	InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
}

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

__EXPORT ScDocShell::~ScDocShell()
{
	ResetDrawObjectShell();	// #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen

	SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
	if (pStlPool)
		EndListening(*pStlPool);
	EndListening(*this);

	delete pAutoStyleList;

	SfxApplication *pSfxApp = SFX_APP();
	if ( pSfxApp->GetDdeService() )				// DDE vor Dokument loeschen
		pSfxApp->RemoveDdeTopic( this );

	delete pDocFunc;
	delete aDocument.mpUndoManager;
	aDocument.mpUndoManager = 0;
    delete pImpl;

	delete pPaintLockData;

	delete pOldJobSetup;		// gesetzt nur bei Fehler in StartJob()

    delete pSolverSaveData;
    delete pSheetSaveData;
    delete pOldAutoDBRange;

    if (pModificator)
    {
        DBG_ERROR("The Modificator should not exist");
        delete pModificator;
    }
}

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

::svl::IUndoManager* __EXPORT ScDocShell::GetUndoManager()
{
	return aDocument.GetUndoManager();
}

void ScDocShell::SetModified( sal_Bool bModified )
{
    if ( SfxObjectShell::IsEnableSetModified() )
	{
    	SfxObjectShell::SetModified( bModified );
		Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) );
	}
}


void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ )
{
	//	BroadcastUno muss auch mit pPaintLockData sofort passieren
	//!	auch bei SetDrawModified, wenn Drawing angebunden ist
	//!	dann eigener Hint???

	if ( pPaintLockData && bIsModified )
	{
        // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
        // of RecalcModeAlways formulas (like OFFSET) after modifying cells
        aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
        aDocument.InvalidateTableArea();    // #i105279# needed here
        aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );

		pPaintLockData->SetModified();			// spaeter...
		return;
	}

	SetDrawModified( bIsModified );

	if ( bIsModified )
	{
		if ( aDocument.IsAutoCalcShellDisabled() )
			SetDocumentModifiedPending( sal_True );
		else
		{
			SetDocumentModifiedPending( sal_False );
            aDocument.InvalidateStyleSheetUsage();
			aDocument.InvalidateTableArea();
            aDocument.InvalidateLastTableOpParams();
			aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
			if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() )
				aDocument.CalcFormulaTree( sal_True );
			PostDataChanged();

			//	Detective AutoUpdate:
			//	Update if formulas were modified (DetectiveDirty) or the list contains
			//	"Trace Error" entries (#75362# - Trace Error can look completely different
			//	after changes to non-formula cells).

			ScDetOpList* pList = aDocument.GetDetOpList();
			if ( pList && ( aDocument.IsDetectiveDirty() || pList->HasAddError() ) &&
				 pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
			{
				GetDocFunc().DetectiveRefresh(sal_True);	// sal_True = caused by automatic update
			}
			aDocument.SetDetectiveDirty(sal_False);			// always reset, also if not refreshed
		}

        // #b6697848# notify UNO objects after BCA_BRDCST_ALWAYS etc.
        aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
	}
}

//	SetDrawModified - ohne Formel-Update
//	(Drawing muss auch beim normalen SetDocumentModified upgedated werden,
//	 z.B. bei Tabelle loeschen etc.)

void ScDocShell::SetDrawModified( sal_Bool bIsModified /* = sal_True */ )
{
	sal_Bool bUpdate = ( bIsModified != IsModified() );

	SetModified( bIsModified );

    SfxBindings* pBindings = GetViewBindings();
	if (bUpdate)
	{
		if (pBindings)
		{
			pBindings->Invalidate( SID_SAVEDOC );
			pBindings->Invalidate( SID_DOC_MODIFIED );
		}
	}

	if (bIsModified)
	{
        if (pBindings)
        {
            // #i105960# Undo etc used to be volatile.
            // They always have to be invalidated, including drawing layer or row height changes
            // (but not while pPaintLockData is set).
            pBindings->Invalidate( SID_UNDO );
            pBindings->Invalidate( SID_REDO );
            pBindings->Invalidate( SID_REPEAT );
        }

		if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
		{
			aDocument.UpdateChartListenerCollection();
			SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED ));	// Navigator
		}
		SC_MOD()->AnythingChanged();
	}
}

void ScDocShell::SetInUndo(sal_Bool bSet)
{
	bIsInUndo = bSet;
}


void ScDocShell::GetDocStat( ScDocStat& rDocStat )
{
	SfxPrinter* pPrinter = GetPrinter();

	aDocument.GetDocStat( rDocStat );
	rDocStat.nPageCount = 0;

	if ( pPrinter )
		for ( SCTAB i=0; i<rDocStat.nTableCount; i++ )
            rDocStat.nPageCount = sal::static_int_cast<sal_uInt16>( rDocStat.nPageCount +
                (sal_uInt16) ScPrintFunc( this, pPrinter, i ).GetTotalPages() );
}


SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog(
										 Window *pParent, const SfxItemSet &rSet )
{
	SfxDocumentInfoDialog* pDlg   = new SfxDocumentInfoDialog( pParent, rSet );
	ScDocShell*			   pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current());

	//nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht
	//aus dem Doc-Manager

	if( pDocSh == this )
	{
		ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
		DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
		::CreateTabPage ScDocStatPageCreate = 	pFact->GetTabPageCreatorFunc( RID_SCPAGE_STAT );
		DBG_ASSERT(ScDocStatPageCreate, "Tabpage create fail!");//CHINA001
		pDlg->AddTabPage( 42,
			ScGlobal::GetRscString( STR_DOC_STAT ),
			ScDocStatPageCreate,
			NULL);
//CHINA001		pDlg->AddTabPage( 42,
//CHINA001		ScGlobal::GetRscString( STR_DOC_STAT ),
//CHINA001		ScDocStatPage::Create,
//CHINA001		NULL );
	}
	return pDlg;
}

Window* ScDocShell::GetActiveDialogParent()
{
	ScTabViewShell* pViewSh	= ScTabViewShell::GetActiveViewShell();
	if ( pViewSh )
		return pViewSh->GetDialogParent();
	else
		return Application::GetDefDialogParent();
}

void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData )
{
    delete pSolverSaveData;
    pSolverSaveData = new ScOptSolverSave( rData );
}

ScSheetSaveData* ScDocShell::GetSheetSaveData()
{
    if (!pSheetSaveData)
        pSheetSaveData = new ScSheetSaveData;

    return pSheetSaveData;
}

void ScDocShell::UseSheetSaveEntries()
{
    if (pSheetSaveData)
    {
        pSheetSaveData->UseSaveEntries();   // use positions from saved file for next saving

        bool bHasEntries = false;
        SCTAB nTabCount = aDocument.GetTableCount();
        SCTAB nTab;
        for (nTab = 0; nTab < nTabCount; ++nTab)
            if (pSheetSaveData->HasStreamPos(nTab))
                bHasEntries = true;

        if (!bHasEntries)
        {
            // if no positions were set (for example, export to other format),
            // reset all "valid" flags

            for (nTab = 0; nTab < nTabCount; ++nTab)
                if (aDocument.IsStreamValid(nTab))
                    aDocument.SetStreamValid(nTab, sal_False);
        }
    }
}

// --- ScDocShellModificator ------------------------------------------

ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS )
		:
		rDocShell( rDS ),
		aProtector( rDS.GetDocument()->GetRefreshTimerControlAddress() )
{
	ScDocument* pDoc = rDocShell.GetDocument();
	bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled();
	bIdleDisabled = pDoc->IsIdleDisabled();
	pDoc->SetAutoCalcShellDisabled( sal_True );
	pDoc->DisableIdle( sal_True );
}


ScDocShellModificator::~ScDocShellModificator()
{
	ScDocument* pDoc = rDocShell.GetDocument();
	pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
	if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() )
		rDocShell.SetDocumentModified();	// last one shuts off the lights
	pDoc->DisableIdle( bIdleDisabled );
}


void ScDocShellModificator::SetDocumentModified()
{
	ScDocument* pDoc = rDocShell.GetDocument();
	if ( !pDoc->IsImportingXML() )
	{
		// AutoCalcShellDisabled temporaer restaurieren
		sal_Bool bDisabled = pDoc->IsAutoCalcShellDisabled();
		pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
		rDocShell.SetDocumentModified();
		pDoc->SetAutoCalcShellDisabled( bDisabled );
	}
	else
	{
		// uno broadcast is necessary for api to work
		// -> must also be done during xml import
		pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
	}
}

//<!--Added by PengYunQuan for Validity Cell Range Picker
sal_Bool ScDocShell::AcceptStateUpdate() const
{
	if( SfxObjectShell::AcceptStateUpdate() )
		return sal_True;

	if( SC_MOD()->Find1RefWindow( SFX_APP()->GetTopWindow() ) )
		return sal_True;

	return sal_False;
}
//-->Added by PengYunQuan for Validity Cell Range Picker


bool ScDocShell::IsChangeRecording() const
{
    ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
    return pChangeTrack != NULL;
}

    
bool ScDocShell::HasChangeRecordProtection() const
{
    bool bRes = false;
    ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
    if (pChangeTrack)
        bRes = pChangeTrack->IsProtected();
    return bRes;
}

    
void ScDocShell::SetChangeRecording( bool bActivate )
{
    bool bOldChangeRecording = IsChangeRecording();

    if (bActivate)
    {
        aDocument.StartChangeTracking();
        ScChangeViewSettings aChangeViewSet;
        aChangeViewSet.SetShowChanges(sal_True);
        aDocument.SetChangeViewSettings(aChangeViewSet);
    }
    else
    {
        aDocument.EndChangeTracking();
        PostPaintGridAll();
    }

    if (bOldChangeRecording != IsChangeRecording())
    {
        UpdateAcceptChangesDialog();
        // Slots invalidieren
        SfxBindings* pBindings = GetViewBindings();
        if (pBindings)
            pBindings->InvalidateAll(sal_False);
    }
}    

        
bool ScDocShell::SetProtectionPassword( const String &rNewPassword )
{
    bool bRes = false;
    ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
    if (pChangeTrack)
    {
        sal_Bool bProtected = pChangeTrack->IsProtected();

        if (rNewPassword.Len())
        {
            // when password protection is applied change tracking must always be active
            SetChangeRecording( true );
        
            ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash;
            SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword );
            pChangeTrack->SetProtection( aProtectionHash );
        }
        else
        {
            pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() );
        }
        bRes = true;

        if ( bProtected != pChangeTrack->IsProtected() )
        {
            UpdateAcceptChangesDialog();
            SetDocumentModified();
        }
    }

    return bRes;
}    

        
bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash )
{
    bool bRes = false;
    ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
    if (pChangeTrack && pChangeTrack->IsProtected())
    {
        rPasswordHash = pChangeTrack->GetProtection();
        bRes = true;
    }
    return bRes;
}    

void ScDocShell::BeforeLoading( SfxMedium& /*rMedium*/, const ::rtl::OUString & rstrTypeName, const ::rtl::OUString & /*rstrFilterName*/ )
{
    const sal_uInt8 nMediumFlag = GetMediumFlag<false>( rstrTypeName );

    if( nMediumFlag & E_MEDIUM_FLAG_MSXML )
    {
        aDocument.SetImportingMSXML( true );

        if ( GetCreateMode() != SFX_CREATE_MODE_ORGANIZER )
            ScColumn::bDoubleAlloc = sal_True;
    }
}

void ScDocShell::AfterLoading( SfxMedium& /*rMedium*/, const ::rtl::OUString & rstrTypeName, const ::rtl::OUString & /*rstrFilterName*/ )
{
    const sal_uInt8 nMediumFlag = GetMediumFlag<false>( rstrTypeName );

	if( nMediumFlag & E_MEDIUM_FLAG_MSXML )
	{
        aDocument.SetImportingMSXML( false );

        if ( GetCreateMode() != SFX_CREATE_MODE_ORGANIZER )
            ScColumn::bDoubleAlloc = sal_False;
    
		// After loading, the XEmbeddedObject was probably set modified flag, so reset the flag to false.
		uno::Sequence < ::rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();
		for ( sal_Int32 n = 0; n < aNames.getLength(); n++ )
		{
			::rtl::OUString	aName = aNames[n];
			uno::Reference < embed::XEmbeddedObject > xObj = GetEmbeddedObjectContainer().GetEmbeddedObject( aName );
			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->setModified(sal_False);
					}
				}
				catch( uno::Exception& )
				{}
			}
		}
	}
}
        
