/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: starmath_document.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 19:56:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop


#ifndef _SVTOOLS_LINGUCFG_HXX_
#include <svtools/lingucfg.hxx>
#endif
#ifndef _SO_CLSIDS_HXX //autogen
#include <so3/clsids.hxx>
#endif



#ifndef _SFXENUMITEM_HXX //autogen
#include <svtools/eitem.hxx>
#endif
#ifndef _SFX_WHITER_HXX //autogen
#include <svtools/whiter.hxx>
#endif
#ifndef _SFXINTITEM_HXX //autogen
#include <svtools/intitem.hxx>
#endif
#ifndef _SFXSTRITEM_HXX //autogen
#include <svtools/stritem.hxx>
#endif

#ifndef _SFXDISPATCH_HXX //autogen
#include <bf_sfx2/dispatch.hxx>
#endif
#ifndef _SFXDOCFILE_HXX //autogen
#include <bf_sfx2/docfile.hxx>
#endif
#ifndef _SFXREQUEST_HXX //autogen
#include <bf_sfx2/request.hxx>
#endif
#ifndef _SFXECODE_HXX //autogen
#include <svtools/sfxecode.hxx>
#endif
#ifndef _SFX_PRINTER_HXX //autogen
#include <bf_sfx2/printer.hxx>
#endif
#ifndef _SFXITEMPOOL_HXX
#include <svtools/itempool.hxx>
#endif
#ifndef _MyEDITENG_HXX
#include <bf_svx/editeng.hxx>
#endif
#ifndef _EEITEM_HXX
#include <bf_svx/eeitem.hxx>
#endif
#ifndef _EDITSTAT_HXX
#include <bf_svx/editstat.hxx>
#endif
#ifndef _EEITEMID_HXX
#include <bf_svx/eeitemid.hxx>
#endif
#ifndef _SVX_FONTITEM_HXX
#include <bf_svx/fontitem.hxx>
#endif
#ifndef _SVX_FHGTITEM_HXX
#include <bf_svx/fhgtitem.hxx>
#endif
#ifndef _SFXSLSTITM_HXX
#include <svtools/slstitm.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif

#ifndef STARMATH_HRC
#include <starmath.hrc>
#endif
#ifndef DOCUMENT_HXX
#include <document.hxx>
#endif
#ifndef UNOMODEL_HXX
#include <unomodel.hxx>
#endif
#ifndef TOOLBOX_HXX
#include <toolbox.hxx>
#endif
#ifndef ACTION_HXX
#include <action.hxx>
#endif
#ifndef VIEW_HXX
#include <view.hxx>
#endif
#ifndef MATHML_HXX
#include <mathml.hxx>
#endif
namespace binfilter {



using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::accessibility;

#define A2OU(x)        ::rtl::OUString::createFromAscii( x )

#ifndef SO2_DECL_SVSTORAGESTREAM_DEFINED
#define SO2_DECL_SVSTORAGESTREAM_DEFINED
SO2_DECL_REF(SvStorageStream)
#endif
#ifndef SO2_DECL_SVSTORAGE_DEFINED
#define SO2_DECL_SVSTORAGE_DEFINED
SO2_DECL_REF(SvStorage)
#endif

#define DOCUMENT_BUFFER_SIZE	(USHORT)32768

static const char __FAR_DATA pStarMathDoc[] = "StarMathDocument";


/**************************************************************************/
/*
**
**	CLASS IMPLEMENTATION
**
**/

#define SmDocShell
#include "smslots.hxx"

/*N*/ TYPEINIT1( SmDocShell, SfxObjectShell );

/*N*/ SFX_IMPL_INTERFACE(SmDocShell, SfxObjectShell, SmResId(0))
/*N*/ {
/*N*/ //	  SFX_OBJECTBAR_REGISTRATION(
/*N*/ //		  SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER,
/*N*/ //		  SmResId(RID_DEFAULTTOOLBOX));
/*N*/ }

#if 0

//JP 13.06.00: das fehlt vwohl noch, oder??
//	SfxObjectFactory& rFactory = (SfxObjectFactory&)Factory();
//	SfxFactoryFilterContainer *pFltContainer = rFactory.GetFilterContainer( FALSE );
//	rFactory.GetFilterContainer()->SetDetectFilter( &SmDLL::DetectFilter );

   // FG: Sonst gibts keine Hilfe im Math  #38447#
#else
/*N*/ SFX_IMPL_OBJECTFACTORY_DLL(SmDocShell, smath, SvGlobalName(BF_SO3_SM_CLASSID), Sm);
#endif




/*N*/ SmSymSetManager & SmDocShell::GetSymSetManager()
/*N*/ {
/*N*/ 	if (!pSymSetMgr)
/*N*/     {
/*N*/ 		pSymSetMgr = new SmSymSetManager;
/*N*/         pSymSetMgr->Load();
/*N*/     }
/*N*/ 	return *pSymSetMgr;
/*N*/ }








/*N*/ void SmDocShell::SetText(const String& rBuffer)
/*N*/ {
/*N*/ 	if (rBuffer != aText)
/*N*/ 	{
/*N*/ 		BOOL bIsEnabled = IsEnableSetModified();
/*N*/ 		if( bIsEnabled )
/*N*/ 			EnableSetModified( FALSE );
/*N*/
/*N*/ 		aText = rBuffer;
/*N*/ 		Parse();
/*N*/         //Resize();
/*N*/ 		SmViewShell *pViewSh = SmGetActiveView();
/*N*/ 		if( pViewSh )
/*N*/         {
/*N*/ 			pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT);
/*N*/ 			if ( GetProtocol().IsInPlaceActive() || SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
/*N*/                 Resize();
/*N*/             else
/*N*/                 pViewSh->GetGraphicWindow().Invalidate();
/*N*/         }
/*N*/
/*N*/ 		if ( bIsEnabled )
/*N*/ 			EnableSetModified( bIsEnabled );
/*N*/ 		SetModified(TRUE);
/*N*/
        // launch accessible event if necessary
/*N*/ 	}
/*N*/ }



/*N*/ void SmDocShell::Parse()
/*N*/ {
/*N*/ 	if (pTree)
/*N*/ 		delete pTree;
/*N*/ 	pTree = aInterpreter.Parse(aText);
/*N*/ 	nModifyCount++;
/*N*/     SetFormulaArranged( FALSE );
/*N*/ }


/*N*/ void SmDocShell::ArrangeFormula()
/*N*/ {
/*N*/   //! Nur fuer die Dauer der Existenz dieses Objekts sind am Drucker die
/*N*/ 	//! richtigen Einstellungen garantiert.
/*N*/     SmPrinterAccess  aPrtAcc(*this);
/*N*/ //	OutputDevice	*pOutDev = aPrtAcc.GetPrinter();
/*N*/     OutputDevice* pOutDev = aPrtAcc.GetRefDev();
/*N*/
/*N*/ #ifndef PRODUCT
/*N*/ 	if (!pOutDev)
/*N*/ 		DBG_WARNING("Sm : kein Drucker vorhanden");
/*N*/ #endif
/*N*/
/*N*/   // falls noetig ein anderes OutputDevice holen fuer das formatiert wird
/*N*/ 	if (!pOutDev)
/*N*/ 	{
/*N*/ 		SmViewShell *pView = SmGetActiveView();
/*N*/ 		if (pView)
/*N*/ 			pOutDev = &pView->GetGraphicWindow();
/*N*/ 		else
/*N*/         {   pOutDev = &SM_MOD1()->GetDefaultVirtualDev();
/*N*/ 			pOutDev->SetMapMode( MapMode(MAP_100TH_MM) );
/*N*/ 		}
/*N*/ 	}
/*N*/ 	DBG_ASSERT(pOutDev->GetMapMode().GetMapUnit() == MAP_100TH_MM,
/*N*/ 			   "Sm : falscher MapMode");
/*N*/
/*N*/ 	const SmFormat &rFormat = GetFormat();
/*N*/ 	pTree->Prepare(rFormat, *this);
/*N*/ 	pTree->Arrange(*pOutDev, rFormat);
/*N*/
/*N*/ 	SetFormulaArranged(TRUE);
/*N*/
/*N*/     // invalidate accessible text
/*N*/     aAccText = String();
/*N*/ }


/*N*/ EditEngine& SmDocShell::GetEditEngine()
/*N*/ {
/*N*/ 	if (!pEditEngine)
/*N*/ 	{
/*N*/         //!
/*N*/         //! see also SmEditWindow::DataChanged !
/*N*/         //!
/*N*/
/*N*/ 		pEditEngineItemPool = EditEngine::CreatePool();
/*N*/
/*N*/         //
/*N*/         // set fonts to be used
/*N*/         //
/*N*/         SvtLinguOptions aOpt;
/*N*/         SvtLinguConfig().GetOptions( aOpt );
/*N*/         //
/*N*/         struct FontDta {
/*N*/             INT16       nFallbackLang;
/*N*/             INT16       nLang;
/*N*/             USHORT      nFontType;
/*N*/             USHORT      nFontInfoId;
/*N*/             } aTable[3] =
/*N*/         {
/*N*/             // info to get western font to be used
/*N*/             {   LANGUAGE_ENGLISH_US,    LANGUAGE_NONE,
/*N*/                 DEFAULTFONT_SERIF,      EE_CHAR_FONTINFO },
/*N*/             // info to get CJK font to be used
/*N*/             {   LANGUAGE_JAPANESE,      LANGUAGE_NONE,
/*N*/                 DEFAULTFONT_CJK_TEXT,   EE_CHAR_FONTINFO_CJK },
/*N*/             // info to get CTL font to be used
/*N*/             {   LANGUAGE_ARABIC,        LANGUAGE_NONE,
/*N*/                 DEFAULTFONT_CTL_TEXT,   EE_CHAR_FONTINFO_CTL }
/*N*/         };
/*N*/         aTable[0].nLang = aOpt.nDefaultLanguage;
/*N*/         aTable[1].nLang = aOpt.nDefaultLanguage_CJK;
/*N*/         aTable[2].nLang = aOpt.nDefaultLanguage_CTL;
/*N*/         //
/*N*/         for (int i = 0;  i < 3;  ++i)
/*N*/         {
/*N*/             const FontDta &rFntDta = aTable[i];
/*N*/             LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ?
/*N*/                     rFntDta.nFallbackLang : rFntDta.nLang;
/*N*/             Font aFont = Application::GetDefaultDevice()->GetDefaultFont(
/*N*/                         rFntDta.nFontType, nLang, DEFAULTFONT_FLAGS_ONLYONE );
/*N*/             pEditEngineItemPool->SetPoolDefaultItem(
/*N*/                     SvxFontItem( aFont.GetFamily(), aFont.GetName(),
/*N*/                         aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(),
/*N*/                         rFntDta.nFontInfoId ) );
/*N*/         }
/*N*/
/*N*/         // set font heights
/*N*/ 		SvxFontHeightItem aFontHeigt(
/*N*/ 						Application::GetDefaultDevice()->LogicToPixel(
/*N*/ 						Size( 0, 10 ), MapMode( MAP_POINT ) ).Height(), 100,
/*N*/ 						EE_CHAR_FONTHEIGHT );
/*N*/ 		pEditEngineItemPool->SetPoolDefaultItem( aFontHeigt );
/*N*/ 		aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CJK );
/*N*/ 		pEditEngineItemPool->SetPoolDefaultItem( aFontHeigt );
/*N*/ 		aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CTL );
/*N*/ 		pEditEngineItemPool->SetPoolDefaultItem( aFontHeigt );
/*N*/
/*N*/ 		pEditEngine = new EditEngine( pEditEngineItemPool );
/*N*/
/*N*/ 		pEditEngine->EnableUndo( TRUE );
/*N*/ 		pEditEngine->SetDefTab( USHORT(
/*N*/ 			Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) );
/*N*/
/*N*/ 		pEditEngine->SetControlWord(
/*N*/ 				(pEditEngine->GetControlWord() | EE_CNTRL_AUTOINDENTING) &
/*N*/ 				(~EE_CNTRL_UNDOATTRIBS) &
/*N*/ 				(~EE_CNTRL_PASTESPECIAL) );
/*N*/
/*N*/ 		pEditEngine->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) );
/*N*/ 		pEditEngine->SetRefMapMode( MAP_PIXEL );
/*N*/
/*N*/ 		pEditEngine->SetPaperSize( Size( 800, 0 ) );
/*N*/
/*N*/ 		pEditEngine->EraseVirtualDevice();
/*N*/
/*N*/         // set initial text if the document already has some...
/*N*/         // (may be the case when reloading a doc)
/*N*/         String aTxt( GetText() );
/*N*/         if (aTxt.Len())
/*N*/             pEditEngine->SetText( aTxt );
/*N*/
/*N*/ 		pEditEngine->ClearModifyFlag();
/*N*/
/*N*/ 		// forces new settings to be used if the itempool was modified
/*N*/ 		// after cthe creation of the EditEngine
/*N*/ 		//pEditEngine->Clear();	//#77957 incorrect font size
/*N*/ 	}
/*N*/ 	return *pEditEngine;
/*N*/ }




/*N*/ void SmDocShell::Draw(OutputDevice &rDev, Point &rPosition)
/*N*/ {
/*N*/ 	if (!pTree)
/*?*/ 		Parse();
/*N*/ 	DBG_ASSERT(pTree, "Sm : NULL pointer");
/*N*/
/*N*/ 	if (!IsFormulaArranged())
/*N*/ 		ArrangeFormula();
/*N*/
/*N*/ 	//Problem: Was passiert mit dem WYSIWYG? Wir haben waehrend wir inplace aktiv
/*N*/ 	//sind kein Referenzdevice und sind auch nicht darauf ausgerichtet. Es kann
/*N*/ 	//also jetzt eine Differenz zwischen der VisArea (spricht die Groesse im Client)
/*N*/ 	//und der jetzt vorliegenden Groese geben.
/*N*/ 	//Idee: Die Differenz koennte, zumindest behelfsmaessig, mit SmNod::SetSize
/*N*/ 	//angepasst werden.
/*N*/
/*N*/ 	rPosition.X() += aFormat.GetDistance( DIS_LEFTSPACE );
/*N*/ 	rPosition.Y() += aFormat.GetDistance( DIS_TOPSPACE	);
/*N*/
/*N*/     //! in case of high contrast-mode (accessibility option!)
/*N*/     //! the draw mode needs to be set to default, because when imbedding
/*N*/     //! Math for example in Calc in "a over b" the fraction bar may not
/*N*/     //! be visible else. More generally: the FillColor may have been changed.
/*N*/     ULONG nOldDrawMode = DRAWMODE_DEFAULT;
/*N*/     BOOL bRestoreDrawMode = FALSE;
/*N*/     if (OUTDEV_WINDOW == rDev.GetOutDevType() &&
/*N*/         ((Window &) rDev).GetDisplayBackground().GetColor().IsDark())
/*N*/     {
/*?*/          nOldDrawMode = rDev.GetDrawMode();
/*?*/          rDev.SetDrawMode( DRAWMODE_DEFAULT );
/*?*/          bRestoreDrawMode = TRUE;
/*N*/     }
/*N*/
/*N*/     pTree->Draw(rDev, rPosition);
/*N*/
/*N*/     if (bRestoreDrawMode)
/*?*/         rDev.SetDrawMode( nOldDrawMode );
/*N*/ }



/*N*/ Size SmDocShell::GetSize()
/*N*/ {
/*N*/ 	Size aRet;
/*N*/
/*N*/ 	if (!pTree)
/*N*/ 		Parse();
/*N*/
/*N*/ 	if (pTree)
/*N*/ 	{
/*N*/ 		if (!IsFormulaArranged())
/*N*/ 			ArrangeFormula();
/*N*/ 		aRet = pTree->GetSize();
/*N*/
/*N*/ 		if ( !aRet.Width() )
/*?*/ 			aRet.Width() = 2000;
/*N*/ 		else
/*N*/ 			aRet.Width()  += aFormat.GetDistance( DIS_LEFTSPACE ) +
/*N*/ 							 aFormat.GetDistance( DIS_RIGHTSPACE );
/*N*/ 		if ( !aRet.Height() )
/*?*/ 			aRet.Height() = 1000;
/*N*/ 		else
/*N*/ 			aRet.Height() += aFormat.GetDistance( DIS_TOPSPACE ) +
/*N*/ 							 aFormat.GetDistance( DIS_BOTTOMSPACE );
/*N*/ 	}
/*N*/
/*N*/ 	return aRet;
/*N*/ }

////////////////////////////////////////

/*N*/ SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell )
/*N*/ {
/*N*/ 	if ( 0 != (pPrinter = rDocShell.GetPrt()) )
/*N*/ 	{
/*N*/ 		pPrinter->Push( PUSH_MAPMODE );
/*N*/ 		if ( rDocShell.GetProtocol().IsInPlaceActive() ||
/*N*/ 			 SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
/*N*/ 		{
/*N*/ 			// if it is an embedded object (without it's own printer)
/*N*/ 			// we change the MapMode temporarily.
/*N*/ 			//!If it is a document with it's own printer the MapMode should
/*N*/ 			//!be set correct (once) elsewhere(!), in order to avoid numerous
/*N*/ 			//!superfluous pushing and poping of the MapMode when using
/*N*/ 			//!this class.
/*N*/
/*N*/ 			const MapUnit eOld = pPrinter->GetMapMode().GetMapUnit();
/*?*/  			if ( MAP_100TH_MM != eOld )
/*?*/  			{
/*?*/  				MapMode aMap( pPrinter->GetMapMode() );
/*?*/  				aMap.SetMapUnit( MAP_100TH_MM );
/*?*/  				Point aTmp( aMap.GetOrigin() );
/*?*/  				aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
/*?*/  				aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
/*?*/  				aMap.SetOrigin( aTmp );
/*?*/  				pPrinter->SetMapMode( aMap );
/*?*/  			}
/*N*/ 		}
/*N*/ 	}
/*N*/     if ( 0 != (pRefDev = rDocShell.GetRefDev()) && pPrinter != pRefDev )
/*N*/     {
/*N*/         pRefDev->Push( PUSH_MAPMODE );
/*N*/         if ( rDocShell.GetProtocol().IsInPlaceActive() ||
/*N*/              SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() )
/*N*/         {
/*N*/             // if it is an embedded object (without it's own printer)
/*N*/             // we change the MapMode temporarily.
/*N*/             //!If it is a document with it's own printer the MapMode should
/*N*/             //!be set correct (once) elsewhere(!), in order to avoid numerous
/*N*/             //!superfluous pushing and poping of the MapMode when using
/*N*/             //!this class.
/*N*/
/*N*/             const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit();
/*N*/             if ( MAP_100TH_MM != eOld )
/*N*/             {
/*N*/                 MapMode aMap( pRefDev->GetMapMode() );
/*N*/                 aMap.SetMapUnit( MAP_100TH_MM );
/*N*/                 Point aTmp( aMap.GetOrigin() );
/*N*/                 aTmp.X() = OutputDevice::LogicToLogic( aTmp.X(), eOld, MAP_100TH_MM );
/*N*/                 aTmp.Y() = OutputDevice::LogicToLogic( aTmp.Y(), eOld, MAP_100TH_MM );
/*N*/                 aMap.SetOrigin( aTmp );
/*N*/                 pRefDev->SetMapMode( aMap );
/*N*/             }
/*N*/         }
/*N*/     }
/*N*/ }

/*N*/ SmPrinterAccess::~SmPrinterAccess()
/*N*/ {
/*N*/ 	if ( pPrinter )
/*N*/ 		pPrinter->Pop();
/*N*/     if ( pRefDev && pRefDev != pPrinter )
/*N*/         pRefDev->Pop();
/*N*/ }

////////////////////////////////////////

/*N*/ Printer* SmDocShell::GetPrt()
/*N*/ {
/*N*/ 	if ( GetProtocol().IsInPlaceActive() ||
/*N*/  		 SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
/*N*/ 	{
/*N*/ 		//Normalerweise wird der Printer vom Server besorgt. Wenn dieser aber
/*N*/ 		//keinen liefert (weil etwa noch keine connection da ist), kann es
/*N*/ 		//dennoch sein, dass wir den Printer kennen, denn dieser wird in
/*N*/ 		//OnDocumentPrinterChanged vom Server durchgereicht und dann temporaer
/*N*/ 		//festgehalten.
/*N*/         Printer *pPrt = GetDocumentPrinter();
/*N*/         if ( !pPrt && pTmpPrinter )
/*N*/             pPrt = pTmpPrinter;
/*N*/         return pPrt;
/*N*/ 	}
/*N*/ 	else if ( !pPrinter )
/*N*/ 	{
/*N*/ 		SfxItemSet *pOptions =
/*N*/ 			new SfxItemSet(GetPool(),
/*N*/ 						   SID_PRINTSIZE,		SID_PRINTSIZE,
/*N*/ 						   SID_PRINTZOOM,		SID_PRINTZOOM,
/*N*/ 						   SID_PRINTTITLE,		SID_PRINTTITLE,
/*N*/ 						   SID_PRINTTEXT,		SID_PRINTTEXT,
/*N*/ 						   SID_PRINTFRAME,		SID_PRINTFRAME,
/*N*/ 						   SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES,
/*N*/ 						   0);
/*N*/
/*N*/ 		SmModule *pp = SM_MOD1();
/*N*/ 		pp->GetConfig()->ConfigToItemSet(*pOptions);
/*N*/ 		pPrinter = new SfxPrinter(pOptions);
/*N*/ 		pPrinter->SetMapMode( MapMode(MAP_100TH_MM) );
/*N*/ 	}
/*N*/ 	return pPrinter;
/*N*/ }

/*N*/ OutputDevice* SmDocShell::GetRefDev()
/*N*/ {
/*N*/     if ( GetProtocol().IsInPlaceActive() ||
/*N*/          SFX_CREATE_MODE_EMBEDDED == GetCreateMode() )
/*N*/     {
/*N*/         OutputDevice* pOutDev = GetDocumentRefDev();
/*N*/         if ( pOutDev )
/*N*/             return pOutDev;
/*N*/     }
/*N*/
/*N*/     return GetPrt();
/*N*/ }


/*N*/ void SmDocShell::SetPrinter( SfxPrinter *pNew )
/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001
/*N*/ }

/*N*/ void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt )
/*N*/ {
/*N*/ 	pTmpPrinter = pPrt;
/*N*/ 	SetFormulaArranged(FALSE);
/*N*/ 	SM_MOD1()->GetRectCache()->Reset();
/*N*/ 	Size aOldSize = GetVisArea().GetSize();
/*N*/ 	Resize();
/*N*/ 	if( aOldSize != GetVisArea().GetSize() && aText.Len() )
/*N*/ 		SetModified( TRUE );
/*N*/ 	pTmpPrinter = 0;
/*N*/ }

/*N*/ void SmDocShell::Resize()
/*N*/ {
/*N*/ 	Size aVisSize = GetSize();
/*N*/
/*N*/ 	BOOL bIsEnabled = IsEnableSetModified();
/*N*/ 	if ( bIsEnabled )
/*?*/ 		EnableSetModified( FALSE );
/*N*/
/*N*/ 	SetVisAreaSize( aVisSize );
/*N*/ 	SmViewShell *pViewSh = SmGetActiveView();
/*N*/ 	if (pViewSh)
/*?*/         pViewSh->GetGraphicWindow().Invalidate();
/*N*/
/*N*/ 	if ( bIsEnabled )
/*?*/ 		EnableSetModified( bIsEnabled );
/*N*/ }


/*N*/ SmDocShell::SmDocShell(SfxObjectCreateMode eMode) :
/*N*/ 	SfxObjectShell(eMode),
/*N*/ 	pSymSetMgr			( 0 ),
/*N*/ 	pTree				( 0 ),
/*N*/ 	pPrinter			( 0 ),
/*N*/ 	pTmpPrinter			( 0 ),
/*N*/ 	pEditEngineItemPool	( 0 ),
/*N*/ 	pEditEngine			( 0 ),
/*N*/ 	nModifyCount		( 0 ),
/*N*/ 	bIsFormulaArranged	( FALSE )
/*N*/ {
/*N*/ 	SetPool(&SFX_APP()->GetPool());
/*N*/
/*N*/ 	SmModule *pp = SM_MOD1();
/*N*/     aFormat = pp->GetConfig()->GetStandardFormat();
/*N*/
/*N*/ 	StartListening(aFormat);
/*N*/ 	StartListening(*pp->GetConfig());
/*N*/
/*N*/ 	SetShell(this);
/*N*/ 	SetModel( new SmModel(this) );	//! das hier mit new erzeugte Model brauch
/*N*/                                   //! im Destruktor nicht explizit geloescht werden.
/*N*/ 									//! Dies erledigt das Sfx.
/*N*/ }



/*N*/ SmDocShell::~SmDocShell()
/*N*/ {
/*N*/ 	SmModule *pp = SM_MOD1();
/*N*/
/*N*/ 	EndListening(aFormat);
/*N*/ 	EndListening(*pp->GetConfig());
/*N*/
/*N*/ 	delete pEditEngine;
/*N*/ 	delete pEditEngineItemPool;
/*N*/ 	delete pTree;
/*N*/ 	delete pPrinter;
/*N*/ }



/*N*/ void SmDocShell::ConvertText( String &rText, SmConvert eConv )
/*N*/     // adapts the text 'rText' that suits one office version to be
/*N*/     // usable in another office version.
/*N*/     // Example: "2 over sin x" acts very different in 4.0 and 5.0,
/*N*/     // and from 5.2 to 6.0 many symbol names were renamed.
/*N*/ {
/*N*/ 	if (pTree)
/*N*/ 		delete pTree;
/*N*/
/*N*/     SmConvert  eTmpConv = aInterpreter.GetConversion();
/*N*/
/*N*/     // parse in old style and make changes for new style
/*N*/     aInterpreter.SetConversion(eConv);
/*N*/     pTree = aInterpreter.Parse(rText);
/*N*/     // get to new version converted text
/*N*/     rText = aInterpreter.GetText();
/*N*/
/*N*/     aInterpreter.SetConversion(eTmpConv);
/*N*/
/*N*/ 	// clean up tree parsed in old style
/*N*/ 	if (pTree)
/*N*/ 	{	delete pTree;
/*N*/ 		pTree = NULL;
/*N*/ 	}
/*N*/ }








/*N*/ BOOL SmDocShell::InitNew(SvStorage * pStor)
/*N*/ {
/*N*/ 	BOOL bRet = FALSE;
/*N*/ 	if (SfxInPlaceObject::InitNew(pStor))
/*N*/ 	{
/*N*/ 		bRet = TRUE;
/*N*/ 		SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000)));
/*N*/ #if 0
/*N*/ 		if (pStor)
/*N*/ 		{
/*N*/ 			aDocStream = pStor->OpenStream(String::CreateFromAscii(pStarMathDoc));
/*N*/ 			aDocStream->SetVersion (pStor->GetVersion ());
/*N*/ 			GetPool().SetFileFormatVersion(USHORT(pStor->GetVersion()));
/*N*/
/*N*/ 			if (! aDocStream )
/*N*/ 				bRet = FALSE;
/*N*/ 		}
/*N*/ #endif
/*N*/ 	}
/*N*/ 	return bRet;
/*N*/ }


/*N*/ BOOL SmDocShell::Load(SvStorage *pStor)
/*N*/ {
/*N*/ 	BOOL bRet = FALSE;
/*N*/ 	if( SfxInPlaceObject::Load( pStor ))
/*N*/ 	{
/*N*/ 		String aTmpStr( C2S( "Equation Native" ));
/*N*/ 		if( pStor->IsStream( aTmpStr ))
/*N*/ 		{
/*N*/ 			// is this a MathType Storage?
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/  			MathType aEquation(aText);
/*N*/ 		}
/*N*/ 		else if( pStor->IsStream(C2S("content.xml")) ||
/*N*/ 				 pStor->IsStream(C2S("Content.xml")) )
/*N*/ 		{
/*?*/  			// is this a fabulous math package ?
/*?*/              Reference< ::com::sun::star::frame::XModel> xModel(GetModel());
/*?*/  			SmXMLWrapper aEquation(xModel);
/*?*/  			SfxMedium aMedium(pStor);
/*?*/              ULONG nError = aEquation.Import(aMedium);
/*?*/              bRet = 0 == nError;
/*?*/              SetError( nError );
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/             bRet = Try3x(pStor, STREAM_READWRITE);
/*N*/
/*N*/ 			if( !bRet )
/*N*/ 			{
/*?*/  				pStor->Remove(String::CreateFromAscii(pStarMathDoc));
/*?*/                   bRet = Try2x(pStor, STREAM_READWRITE);
/*?*/  				pStor->Remove(C2S("\1Ole10Native"));
/*N*/ 			}
/*N*/ 			else
/*N*/             {
/*N*/                 long nVersion = pStor->GetVersion();
/*N*/                 if ( nVersion <= SOFFICE_FILEFORMAT_40 )
/*N*/                     ConvertText( aText, CONVERT_40_TO_50 );
/*N*/                 if ( nVersion <= SOFFICE_FILEFORMAT_50 )
/*N*/                     ConvertText( aText, CONVERT_50_TO_60 );
/*N*/                 if (pTree)
/*?*/                 {   delete pTree;
/*?*/                     pTree = NULL;
/*N*/                 }
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ 	FinishedLoading( SFX_LOADED_ALL );
/*N*/ 	return bRet;
/*N*/ }




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

/*N*/ void SmDocShell::ImplSave( SvStorageStreamRef xStrm )
/*N*/ {
/*N*/     String aTmp( aText );
/*N*/     if (SOFFICE_FILEFORMAT_50 >= xStrm->GetVersion())
/*N*/         ConvertText( aTmp, CONVERT_60_TO_50 );
/*N*/     ByteString exString( ExportString( aTmp ) );
/*N*/
/*N*/ 	*xStrm	<< SM304AIDENT << SM50VERSION
/*N*/ 			<< 'T';
/*N*/ 	xStrm->WriteByteString(exString);
/*N*/ 	*xStrm	<< 'F' << aFormat
/*N*/             << 'S';
/*N*/     xStrm->WriteByteString( ExportString(C2S("unknown")) );
/*N*/     *xStrm  << (USHORT) 0
/*N*/ 			<< '\0';
/*N*/ }

/*N*/ BOOL SmDocShell::Save()
/*N*/ {
/*N*/     //! apply latest changes if necessary
/*N*/     UpdateText();
/*N*/
/*N*/     if ( SfxInPlaceObject::Save() )
/*N*/ 	{
/*N*/ 		if( !pTree )
/*N*/ 			Parse();
/*N*/ 		if( pTree && !IsFormulaArranged() )
/*N*/ 			ArrangeFormula();
/*N*/
/*N*/ 		SvStorage *pStor = GetStorage();
/*N*/ 		if(pStor->GetVersion() >= SOFFICE_FILEFORMAT_60)
/*N*/ 		{
/*N*/ 			// a math package as a storage
/*N*/             Reference< ::com::sun::star::frame::XModel> xModel(GetModel());
/*N*/ 			SmXMLWrapper aEquation(xModel);
/*N*/ 			SfxMedium aMedium(pStor);
/*N*/ 			aEquation.SetFlat(sal_False);
/*N*/ 			return aEquation.Export(aMedium);
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*?*/ 			aDocStream = pStor->OpenStream(String::CreateFromAscii(pStarMathDoc));
/*?*/ 			aDocStream->SetVersion (pStor->GetVersion ());
/*?*/ 			GetPool().SetFileFormatVersion(USHORT(pStor->GetVersion()));
/*?*/
/*?*/ 			aDocStream->Seek(0);
/*?*/ 			ImplSave( aDocStream );
/*?*/
/*?*/ 			aDocStream.Clear();
/*?*/ 			return TRUE;
/*N*/ 		}
/*N*/ 	}
/*N*/ 	return FALSE;
/*N*/ }


/*N*/ void SmDocShell::UpdateText()
/*N*/ {
/*N*/     if (pEditEngine && pEditEngine->IsModified())
/*N*/     {
/*N*/         String aEngTxt( pEditEngine->GetText( LINEEND_LF ) );
/*N*/         if (GetText() != aEngTxt)
/*N*/             SetText( aEngTxt );
/*N*/     }
/*N*/ }


/*N*/ BOOL SmDocShell::SaveAs(SvStorage * pNewStor)
/*N*/ {
/*N*/ 	BOOL bRet = FALSE;
/*N*/
/*N*/     //! apply latest changes if necessary
/*N*/     UpdateText();
/*N*/
/*N*/     if ( SfxInPlaceObject::SaveAs( pNewStor ) )
/*N*/ 	{
/*N*/ 		if( !pTree )
/*?*/ 			Parse();
/*N*/ 		if( pTree && !IsFormulaArranged() )
/*?*/ 			ArrangeFormula();
/*N*/
/*N*/ 		if (pNewStor->GetVersion() >= SOFFICE_FILEFORMAT_60)
/*N*/ 		{
/*N*/ 			// a math package as a storage
/*?*/              Reference< ::com::sun::star::frame::XModel> xModel(GetModel());
/*?*/  			SmXMLWrapper aEquation(xModel);
/*?*/  			SfxMedium aMedium(pNewStor);
/*?*/  			aEquation.SetFlat(sal_False);
/*?*/  			bRet = aEquation.Export(aMedium);
/*N*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/ 			SvStorageStreamRef aStm = pNewStor->OpenStream(
/*N*/ 										String::CreateFromAscii(pStarMathDoc));
/*N*/ 			aStm->SetVersion( pNewStor->GetVersion() );
/*N*/ 			GetPool().SetFileFormatVersion( USHORT( pNewStor->GetVersion() ));
/*N*/ 			aStm->SetBufferSize(DOCUMENT_BUFFER_SIZE);
/*N*/ 			aStm->SetKey( pNewStor->GetKey() ); // Passwort setzen
/*N*/
/*N*/ 			if ( aStm.Is() )
/*N*/ 			{
/*N*/ 				ImplSave( aStm );
/*N*/ 				bRet = TRUE;
/*N*/ 			}
/*N*/ 		}
/*N*/ 	}
/*N*/ 	return bRet;
/*N*/ }


/*N*/ BOOL SmDocShell::SaveCompleted(SvStorage * pStor)
/*N*/ {
/*N*/ 	if( SfxInPlaceObject::SaveCompleted( pStor ))
/*N*/ 	{
/*N*/ #if 0
/*N*/ 		if (! pStor)
/*N*/ 			return TRUE;
/*N*/
/*N*/ 		aDocStream = pStor->OpenStream(String::CreateFromAscii(pStarMathDoc));
/*N*/ 		aDocStream->SetVersion (pStor->GetVersion ());
/*N*/ 		GetPool().SetFileFormatVersion(USHORT(pStor->GetVersion()));
/*N*/ 		aDocStream->SetBufferSize(DOCUMENT_BUFFER_SIZE);
/*N*/ 		aDocStream->SetKey( pStor->GetKey() ); // Passwort setzen
/*N*/ 		return aDocStream.Is();
/*N*/ #endif
/*N*/ 		return TRUE;
/*N*/ 	}
/*N*/ 	return FALSE;
/*N*/ }





/*N*/ void SmDocShell::Execute(SfxRequest& rReq)
/*N*/ {
/*N*/ 	SfxBindings *pBindings	= NULL;
/*N*/ 	SmViewShell *pViewSh	= SmGetActiveView();
/*N*/ 	if (pViewSh)
/*?*/ 		pBindings = &pViewSh->GetViewFrame()->GetBindings();
/*N*/ 	switch (rReq.GetSlot())
/*N*/ 	{
/*N*/ 	case SID_TEXTMODE:
/*N*/ 		{
/*?*/ 			SmFormat  &rFormat = GetFormat();
/*?*/ 			rFormat.SetTextmode(!rFormat.IsTextmode());
/*?*/ 			rFormat.RequestApplyChanges();
/*N*/ 		}
/*N*/ 		break;
/*N*/
/*?*/ 	case SID_AUTO_REDRAW :
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SmModule *pp = SM_MOD1();
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_SYMBOLS_CATALOGUE:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SmSymbolDialog(NULL, GetSymSetManager()).Execute();
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_TOOLBOX:
/*?*/ 		{
/*?*/ 			SmViewShell *pView = SmGetActiveView();
/*?*/ 			if (pView)
/*?*/ 			{DBG_BF_ASSERT(0, "STRIP"); //STRIP001
/*?*/ 			}
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_INSERT_FORMULA:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SfxMedium *pMedium = SFX_APP()->
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_LOADSYMBOLS:
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 		LoadSymbols();
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_SAVESYMBOLS:
/*?*/ 		{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 		SaveSymbols();
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_FONT:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SmFontTypeDialog *pFontTypeDialog = new SmFontTypeDialog(NULL);
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_FONTSIZE:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SmFontSizeDialog *pFontSizeDialog = new SmFontSizeDialog(NULL);
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_DISTANCE:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SmDistanceDialog *pDistanceDialog = new SmDistanceDialog(NULL);
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_ALIGN:
/*?*/ 		{
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 /*?*/ 			SmAlignDialog *pAlignDialog = new SmAlignDialog(NULL);
/*?*/ 		}
/*N*/ 		break;
/*N*/
/*N*/ 	case SID_TEXT:
/*N*/ 		{
/*N*/ 			const SfxStringItem& rItem =
/*N*/ 				(const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXT);
/*N*/
/*N*/ 			if (GetText() != rItem.GetValue())
/*N*/ 			{
/*?*/ 				SetText(rItem.GetValue());
/*N*/ 			}
/*N*/ 		}
/*N*/ 		break;
/*N*/
/*?*/ 	case SID_COPYOBJECT:
/*?*/ 		{
/*?*/     		Reference< datatransfer::XTransferable > xTrans(
/*?*/        										CreateTransferableSnapshot() );
/*?*/ 			if( xTrans.is() )
/*?*/ 			{
/*?*/ 				Reference< lang::XUnoTunnel> xTnnl( xTrans, uno::UNO_QUERY);
/*?*/ 				if( xTnnl.is() )
/*?*/ 				{
/*?*/ 					TransferableHelper* pTrans = (TransferableHelper*)
/*?*/ 						xTnnl->getSomething(
/*?*/ 								TransferableHelper::getUnoTunnelId() );
/*?*/ 					if( pTrans )
/*?*/ 						pTrans->CopyToClipboard( pViewSh
/*?*/ 											? pViewSh->GetEditWindow() : 0 );
/*?*/ 				}
/*?*/ 			}
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_PASTEOBJECT:
/*?*/ 		{
/*?*/ 			TransferableDataHelper aData( TransferableDataHelper::
/*?*/ 				CreateFromSystemClipboard(pViewSh ? pViewSh->GetEditWindow()
/*?*/ 												  : 0) );
/*?*/ 			SotStorageStreamRef xStrm;
/*?*/ 			SotFormatStringId nId;
/*?*/ 			if( aData.GetTransferable().is() &&
/*?*/ 				( aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBEDDED_OBJ ) ||
/*?*/ 				  (aData.HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) &&
/*?*/ 				   aData.HasFormat( nId = SOT_FORMATSTR_ID_EMBED_SOURCE ))) &&
/*?*/ 				aData.GetSotStorageStream( nId, xStrm ) && xStrm.Is() )
/*?*/ 			{
/*?*/ 				SvStorageRef xStore( new SvStorage( *xStrm ));
/*?*/ 				switch( xStore->GetFormat() )
/*?*/ 				{
/*?*/ 				case SOT_FORMATSTR_ID_STARMATH_60:
/*?*/ 				case SOT_FORMATSTR_ID_STARMATH_50:
/*?*/ 				case SOT_FORMATSTR_ID_STARMATH_40:
/*?*/ //??			case SOT_FORMATSTR_ID_STARMATH:
/*?*/ 					{DBG_BF_ASSERT(0, "STRIP");} //STRIP001 /*?*/ 					Insert( xStore );
/*?*/ 					break;
/*?*/                 default:
/*?*/                     DBG_ERROR( "unexpected format ID" );
/*?*/ 				}
/*?*/                 UpdateText();
/*?*/ 			}
/*?*/ 		}
/*?*/ 		break;
/*?*/
/*?*/ 	case SID_UNDO:
/*?*/ 	case SID_REDO:
/*?*/ 		{
/*?*/ 			SfxUndoManager* pUndoMgr = GetUndoManager();
/*?*/ 			if( pUndoMgr )
/*?*/ 			{
/*?*/ 				USHORT nId = rReq.GetSlot(), nCnt = 1;
/*?*/ 				const SfxItemSet* pArgs = rReq.GetArgs();
/*?*/ 				const SfxPoolItem* pItem;
/*?*/ 				if( pArgs && SFX_ITEM_SET == pArgs->GetItemState( nId, FALSE, &pItem ))
/*?*/ 					nCnt = ((SfxUInt16Item*)pItem)->GetValue();
/*?*/
/*?*/ 				BOOL (SfxUndoManager:: *fnDo)( USHORT );
/*?*/
/*?*/ 				sal_uInt16 nCount;
/*?*/ 				if( SID_UNDO == rReq.GetSlot() )
/*?*/ 				{
/*?*/ 					nCount = pUndoMgr->GetUndoActionCount();
/*?*/ 					fnDo = &SfxUndoManager::Undo;
/*?*/ 				}
/*?*/ 				else
/*?*/ 				{
/*?*/ 					nCount = pUndoMgr->GetRedoActionCount();
/*?*/ 					fnDo = &SfxUndoManager::Redo;
/*?*/ 				}
/*?*/
/*?*/ 				for( ; nCnt && nCount; --nCnt, --nCount )
/*?*/ 					(pUndoMgr->*fnDo)( 0 );
/*?*/ 			}
/*?*/ 		}
/*N*/ 		break;
/*N*/ 	}
/*N*/ }


/*N*/ void SmDocShell::GetState(SfxItemSet &rSet)
/*N*/ {
/*N*/ 	SfxWhichIter aIter(rSet);
/*N*/
/*N*/ 	for (USHORT nWh = aIter.FirstWhich();  0 != nWh;  nWh = aIter.NextWhich())
/*N*/ 	{
/*N*/ 		switch (nWh)
/*N*/ 		{
/*?*/ 		case SID_TEXTMODE:
/*?*/ 			rSet.Put(SfxBoolItem(SID_TEXTMODE, GetFormat().IsTextmode()));
/*?*/ 			break;
/*?*/
/*?*/ 		case SID_DOCTEMPLATE :
/*?*/ 			rSet.DisableItem (SID_DOCTEMPLATE);
/*?*/ 			break;
/*?*/
/*?*/ 		case SID_AUTO_REDRAW :
/*?*/ 			{
/*?*/ 				SmModule  *pp = SM_MOD1();
/*?*/ 				BOOL	   bRedraw = pp->GetConfig()->IsAutoRedraw();
/*?*/
/*?*/ 				rSet.Put (SfxBoolItem(SID_AUTO_REDRAW, bRedraw));
/*?*/ 			}
/*?*/ 			break;
/*?*/
/*?*/ 		case SID_TOOLBOX:
/*?*/ 			{
/*?*/ 				BOOL bState = FALSE;
/*?*/ 				SmViewShell *pView = SmGetActiveView();
/*?*/ 				if (pView)
/*?*/ 				{DBG_BF_ASSERT(0, "STRIP"); //STRIP001
/*?*/ 				}
/*?*/ 				rSet.Put(SfxBoolItem(SID_TOOLBOX, bState));
/*?*/ 			}
/*N*/ 			break;
/*N*/
/*N*/ 		case SID_MODIFYSTATUS:
/*N*/ 			{
/*N*/ 				sal_Unicode cMod = ' ';
/*N*/ 				if (IsModified())
/*?*/ 					cMod = '*';
/*N*/ 				rSet.Put(SfxStringItem(SID_MODIFYSTATUS, String(cMod)));
/*N*/ 			}
/*N*/ 			break;
/*N*/
/*N*/ 		case SID_TEXT:
/*N*/ 			rSet.Put(SfxStringItem(SID_TEXT, GetText()));
/*N*/ 			break;
/*N*/
/*N*/ 		case SID_GRAPHIC:
/*N*/ 			rSet.Put(SfxInt16Item(SID_GRAPHIC, nModifyCount));
/*N*/ 			break;
/*N*/
/*N*/ 		case SID_UNDO:
/*N*/ 		case SID_REDO:
/*N*/ 			{
/*N*/ 				SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this );
/*N*/ 				if( pFrm )
/*N*/ 					pFrm->GetSlotState( nWh, NULL, &rSet );
/*N*/ 				else
/*?*/ 					rSet.DisableItem( nWh );
/*N*/ 			}
/*N*/ 			break;
/*N*/
/*N*/ 		case SID_GETUNDOSTRINGS:
/*N*/ 		case SID_GETREDOSTRINGS:
/*N*/ 			{
/*?*/ 				SfxUndoManager* pUndoMgr = GetUndoManager();
/*?*/ 				if( pUndoMgr )
/*?*/ 				{
/*?*/ 					UniString (SfxUndoManager:: *fnGetComment)( USHORT ) const;
/*?*/
/*?*/ 					sal_uInt16 nCount;
/*?*/ 					if( SID_GETUNDOSTRINGS == nWh )
/*?*/ 					{
/*?*/ 						nCount = pUndoMgr->GetUndoActionCount();
/*?*/ 						fnGetComment = &SfxUndoManager::GetUndoActionComment;
/*?*/ 					}
/*?*/ 					else
/*?*/ 					{
/*?*/ 						nCount = pUndoMgr->GetRedoActionCount();
/*?*/ 						fnGetComment = &SfxUndoManager::GetRedoActionComment;
/*?*/ 					}
/*?*/ 					if( nCount )
/*?*/ 					{
/*?*/ 						String sList;
/*?*/ 						for( sal_uInt16 n = 0; n < nCount; ++n )
/*?*/ 							( sList += (pUndoMgr->*fnGetComment)( n ) )
/*?*/ 									+= '\n';
/*?*/
/*?*/ 						SfxStringListItem aItem( nWh );
/*?*/ 						aItem.SetString( sList );
/*?*/ 						rSet.Put( aItem );
/*?*/ 					}
/*?*/ 				}
/*?*/ 				else
/*?*/ 					rSet.DisableItem( nWh );
/*N*/ 			}
/*N*/ 			break;
/*N*/ 		}
/*N*/ 	}
/*N*/ }














/*N*/ void SmDocShell::HandsOff()
/*N*/ {
/*N*/ 	SfxInPlaceObject::HandsOff();
/*N*/ #if 0
/*N*/ 	aDocStream.Clear();
/*N*/ #endif
/*N*/ }


/*N*/ SfxItemPool& SmDocShell::GetPool()
/*N*/ {
/*N*/ 	return SFX_APP()->GetPool();
/*N*/ }

/*N*/ void SmDocShell::SetVisArea (const Rectangle & rVisArea)
/*N*/ {
/*N*/ 	Rectangle aNewRect (rVisArea);
/*N*/
/*N*/ 	aNewRect.SetPos(Point ());
/*N*/
/*N*/ 	if (! aNewRect.Right ()) aNewRect.Right () = 2000;
/*N*/ 	if (! aNewRect.Bottom ()) aNewRect.Bottom () = 1000;
/*N*/
/*N*/ 	BOOL bIsEnabled = IsEnableSetModified();
/*N*/ 	if ( bIsEnabled )
/*?*/ 		EnableSetModified( FALSE );
/*N*/
/*N*/ 	// If outplace editing, then dont resize the OutplaceWindow. But the
/*N*/ 	// ObjectShell has to resize. Bug 56470
/*N*/ 	BOOL bUnLockFrame;
/*N*/ 	if( ( GetProtocol().IsEmbed() || GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) && !GetProtocol().IsInPlaceActive() && GetFrame() )
/*N*/ 	{
/*?*/ 		GetFrame()->LockAdjustPosSizePixel();
/*?*/ 		bUnLockFrame = TRUE;
/*N*/ 	}
/*N*/ 	else
/*N*/ 		bUnLockFrame = FALSE;
/*N*/
/*N*/ 	SfxInPlaceObject::SetVisArea( aNewRect );
/*N*/
/*N*/ 	if( bUnLockFrame )
/*?*/ 		GetFrame()->UnlockAdjustPosSizePixel();
/*N*/
/*N*/ 	if ( bIsEnabled )
/*?*/ 		EnableSetModified( bIsEnabled );
/*N*/ }


/*N*/ BOOL SmDocShell::Try3x (SvStorage *pStor,
/*N*/ 						StreamMode eMode)
/*N*/
/*N*/ {
/*N*/ 	BOOL bRet = FALSE;
/*N*/
/*N*/ 	SvStorageStreamRef aTempStream = pStor->OpenStream(
/*N*/ 								String::CreateFromAscii(pStarMathDoc), eMode);
/*N*/ 	aTempStream->SetVersion (pStor->GetVersion ());
/*N*/ 	GetPool().SetFileFormatVersion (USHORT(pStor->GetVersion()));
/*N*/ 	aTempStream->SetBufferSize(DOCUMENT_BUFFER_SIZE);
/*N*/ 	aTempStream->SetKey( pStor->GetKey() ); // Passwort setzen
/*N*/
/*N*/ 	if (aTempStream->GetError() == 0)
/*N*/ 	{
/*N*/ 		SvStream*	 pSvStream = aTempStream;
/*N*/ 		char		 cTag;
/*N*/ 		sal_uInt32	 lIdent, lVersion;
/*N*/ 		long		 lTime;
/*N*/ 		sal_uInt32	 lDate;
/*N*/ 		String		 aBuffer;
/*N*/         ByteString   aByteStr;
/*N*/
/*N*/ 		*pSvStream >> lIdent >> lVersion;
/*N*/
/*N*/ 		if ((lIdent == SM30IDENT) || (lIdent == SM30BIDENT) || (lIdent == SM304AIDENT))
/*N*/ 		{
/*N*/ 			DBG_ASSERT((lVersion == SM30VERSION) ||
/*N*/ 					   (lVersion == SM50VERSION), "Illegal file version");
/*N*/
/*N*/ 			*pSvStream >> cTag;
/*N*/             rtl_TextEncoding eEnc = RTL_TEXTENCODING_MS_1252;
/*N*/ 			while (cTag && !pSvStream->IsEof())
/*N*/ 			{
/*N*/ 				switch (cTag)
/*N*/ 				{
/*N*/ 					case 'T':
/*N*/                         pSvStream->ReadByteString( aByteStr );
/*N*/                         aText = ImportString( aByteStr );
/*N*/ 						Parse();
/*N*/ 						break;
/*N*/
/*N*/ 					case 'D':
/*?*/ 						pSvStream->ReadByteString(aBuffer, eEnc);
/*?*/ 						pSvStream->ReadByteString(aBuffer, eEnc);
/*?*/ 						*pSvStream >> lDate >> lTime;
/*?*/ 						pSvStream->ReadByteString(aBuffer, eEnc);
/*?*/ 						*pSvStream >> lDate >> lTime;
/*?*/ 						pSvStream->ReadByteString(aBuffer, eEnc);
/*?*/ 						break;
/*N*/
/*N*/ 					case 'F':
/*N*/ 						*pSvStream >> aFormat;
/*N*/ 						if (lIdent != SM304AIDENT)
/*?*/ 							aFormat.From300To304a ();
/*N*/ 						else if ( lVersion == SM30VERSION )
/*N*/ 						{
/*?*/ 							aFormat.SetDistance(DIS_LEFTSPACE, 100);
/*?*/ 							aFormat.SetDistance(DIS_RIGHTSPACE, 100);
/*?*/ 							aFormat.SetDistance(DIS_TOPSPACE, 100);
/*?*/ 							aFormat.SetDistance(DIS_BOTTOMSPACE, 100);
/*N*/ 						}
/*N*/ 						break;
/*N*/
/*N*/ 					case 'S':
/*N*/ 					{
/*N*/                         String      aTmp;
/*N*/                         USHORT      n;
/*N*/                         pSvStream->ReadByteString(aTmp, eEnc);
/*N*/                         *pSvStream >> n;
/*N*/ 						break;
/*N*/ 					}
/*N*/
/*N*/ 					default:
/*N*/ 						DBG_ASSERT((cTag != 0), "Illegal data tag");
/*N*/ 				}
/*N*/ 				*pSvStream >> cTag;
/*N*/ 			}
/*N*/
/*N*/ 			bRet = TRUE;
/*N*/ #if 0
/*N*/ 			aDocStream = aTempStream;
/*N*/ #endif
/*N*/ 		}
/*N*/ 	}
/*N*/
/*N*/ 	if (!bRet)
/*N*/ 	{
/*N*/ 		// kein Passwort gesetzt --> Datei marode
/*?*/ 		if (pStor->GetKey().Len() == 0)
/*?*/ 		{
/*?*/ 			SetError(ERRCODE_SFX_DOLOADFAILED);
/*?*/ 		}
/*?*/ 		// Passwort gesetzt --> war wohl falsch
/*?*/ 		else
/*?*/ 		{
/*?*/ 			SetError(ERRCODE_SFX_WRONGPASSWORD);
/*?*/ 		}
/*N*/ 	}
/*N*/
/*N*/ 	return bRet;
/*N*/ }



BOOL SmDocShell::Try2x (SvStorage *pStor,
                        StreamMode eMode)
{
    SvStorageStreamRef aTempStream = pStor->OpenStream(C2S("\1Ole10Native"), eMode);
    aTempStream->SetVersion (pStor->GetVersion ());
    GetPool().SetFileFormatVersion(USHORT(pStor->GetVersion ()));

    if (aTempStream->GetError() == SVSTREAM_OK)
    {
        void ReadSM20SymSet(SvStream*, SmSymSet*);

        SvStream*    pSvStream = aTempStream;
        char         cTag;
        sal_uInt32   lIdent, lVersion;
        long         lTime;
        sal_uInt32   lDate;
        UINT32       lDataSize;
        String       aBuffer;
        ByteString   aByteStr;
        SmSymSet    *pSymbolSet;

        *pSvStream >> lDataSize >> lIdent >> lVersion;

        if (lIdent == FRMIDENT)
        {
            DBG_ASSERT((lVersion == FRMVERSION), "Illegal file version");

            *pSvStream >> cTag;
            rtl_TextEncoding eEnc = RTL_TEXTENCODING_MS_1252;
            while (cTag && !pSvStream->IsEof())
            {
                switch (cTag)
                {
                    case 'T':
                        pSvStream->ReadByteString( aByteStr );
                        aText = ImportString( aByteStr );
                        Parse();
                        break;

                    case 'D':
                        {
                            pSvStream->ReadByteString(aBuffer, eEnc);
                            pSvStream->ReadByteString(aBuffer, eEnc);
                            *pSvStream >> lDate >> lTime;
                            pSvStream->ReadByteString(aBuffer, eEnc);
                            *pSvStream >> lDate >> lTime;
                            pSvStream->ReadByteString(aBuffer, eEnc);
                        }
                        break;

                    case 'F':
                        {
                            //SmFormat aFormat;
                            aFormat.ReadSM20Format(*pSvStream);
                            aFormat.From300To304a ();
                        }
                        break;

                    case 'S':
                    {
						// not sure about this...
                        /* ??? pSymbolSet = new SmSymSet();
                        ReadSM20SymSet(pSvStream, pSymbolSet);
                        delete pSymbolSet; */
                        String      aTmp;
                        USHORT      n;
                        pSvStream->ReadByteString(aTmp, eEnc);
                        *pSvStream >> n;
                        break;
                    }

                    default:
                        DBG_ASSERT((cTag != 0), "Illegal data tag");
                }
                *pSvStream >> cTag;
            }

            return TRUE;
        }
    }

    return FALSE;
}




/*N*/ void SmDocShell::FillClass(SvGlobalName* pClassName,
/*N*/ 						   ULONG*  pFormat,
/*N*/ 						   String* pAppName,
/*N*/ 						   String* pFullTypeName,
/*N*/ 						   String* pShortTypeName,
/*N*/ 						   long    nFileFormat) const
/*N*/ {
/*N*/ 	SfxInPlaceObject::FillClass(pClassName, pFormat, pAppName, pFullTypeName,
/*N*/ 								pShortTypeName, nFileFormat);
/*N*/
/*N*/ 	if (nFileFormat == SOFFICE_FILEFORMAT_31)
/*N*/ 	{
/*N*/ 		*pClassName 	= SvGlobalName(BF_SO3_SM_CLASSID_30);
/*N*/ 		*pFormat		= SOT_FORMATSTR_ID_STARMATH;
/*N*/ 		pAppName->AssignAscii( RTL_CONSTASCII_STRINGPARAM("Smath 3.1"));
/*N*/ 		*pFullTypeName	= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_31));
/*N*/ 		*pShortTypeName = String(SmResId(RID_DOCUMENTSTR));
/*N*/ 	}
/*N*/ 	else if (nFileFormat == SOFFICE_FILEFORMAT_40)
/*N*/ 	{
/*N*/ 		*pClassName 	= SvGlobalName(BF_SO3_SM_CLASSID_40);
/*N*/ 		*pFormat		= SOT_FORMATSTR_ID_STARMATH_40;
/*N*/ 		*pFullTypeName	= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_40));
/*N*/ 		*pShortTypeName = String(SmResId(RID_DOCUMENTSTR));
/*N*/ 	}
/*N*/ 	else if (nFileFormat == SOFFICE_FILEFORMAT_50)
/*N*/ 	{
/*N*/ 		*pClassName 	= SvGlobalName(BF_SO3_SM_CLASSID_50);
/*N*/ 		*pFormat		= SOT_FORMATSTR_ID_STARMATH_50;
/*N*/ 		*pFullTypeName	= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_50));
/*N*/ 		*pShortTypeName = String(SmResId(RID_DOCUMENTSTR));
/*N*/ 	}
/*N*/ 	else if (nFileFormat == SOFFICE_FILEFORMAT_60 )
/*N*/ 	{
/*N*/ 		*pFullTypeName	= String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_60));
/*N*/ 		*pShortTypeName = String(SmResId(RID_DOCUMENTSTR));

			// for binfilter, we need the FormatIDs to be set. Not setting them
			// has always been an error (!)
	 		*pClassName 	= SvGlobalName(BF_SO3_SM_CLASSID_60);
	 		*pFormat		= SOT_FORMATSTR_ID_STARMATH_60;

/*N*/ 	}
/*N*/ }


/*N*/ ULONG SmDocShell::GetMiscStatus() const
/*N*/ {
/*N*/ 	return SfxInPlaceObject::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE
/*N*/ 											 | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE;
/*N*/ }

/*N*/ void SmDocShell::SetModified(BOOL bModified)
/*N*/ {
/*N*/ 	if( IsEnableSetModified() )
/*N*/ 		SfxObjectShell::SetModified( bModified );
/*N*/ 	Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED));
/*N*/ }




}
