/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/


#include <sot/formats.hxx>

#include <bf_svtools/lingucfg.hxx>
#include <comphelper/classids.hxx>

#include <bf_svtools/itemset.hxx>
#include <bf_svtools/eitem.hxx>
#include <bf_svtools/whiter.hxx>
#include <bf_svtools/intitem.hxx>
#include <bf_svtools/stritem.hxx>

#include <bf_sfx2/app.hxx>
#include <bf_sfx2/docfile.hxx>
#include <bf_sfx2/request.hxx>
#include <bf_svtools/sfxecode.hxx>
#include <bf_sfx2/printer.hxx>

#include <bf_svtools/itempool.hxx>
#include <bf_svx/editeng.hxx>
#include <bf_svx/eeitem.hxx>
#include <bf_svx/editstat.hxx>
#include <bf_svx/eeitemid.hxx>
#include <bf_svx/fontitem.hxx>
#include <bf_svx/fhgtitem.hxx>
#include <bf_svtools/slstitm.hxx>

#include <com/sun/star/uno/Any.h>
#include <starmath.hrc>
#include <document.hxx>
#include <unomodel.hxx>
#include <config.hxx>
#include <mathml.hxx>

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 )

namespace binfilter
{
#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 pStarMathDoc[] = "StarMathDocument";


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

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

/*N*/ SFX_IMPL_OBJECTFACTORY_DLL(SmDocShell, smath, SvGlobalName(BF_SO3_SM_CLASSID), Sm);

/*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*/
/*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*/ #ifdef DBG_UTIL
/*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*/       pOutDev = &SM_MOD1()->GetDefaultVirtualDev();
/*N*/       pOutDev->SetMapMode( MapMode(MAP_100TH_MM) );
/*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*/ 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::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*/
/*N*/   if ( bIsEnabled )
/*?*/       EnableSetModified( bIsEnabled );
/*N*/ }


/*N*/ SmDocShell::SmDocShell(SfxObjectCreateMode eMode) :
/*N*/   SfxObjectShell(eMode),
/*N*/   pSymSetMgr          ( 0 ),
/*N*/   pTree               ( 0 ),
/*N*/   pEditEngineItemPool ( 0 ),
/*N*/   pEditEngine         ( 0 ),
/*N*/   pPrinter            ( 0 ),
/*N*/   pTmpPrinter         ( 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*/   }
/*N*/   return bRet;
/*N*/ }


BOOL SmDocShell::Load(SvStorage *pStor)
{
    BOOL bRet = FALSE;
    if( SfxInPlaceObject::Load( pStor ))
    {
        String aTmpStr( C2S( "Equation Native" ));
        if( !pStor->IsStream( aTmpStr ) )
        {
            if (  pStor->IsStream(C2S("content.xml"))
               || pStor->IsStream(C2S("Content.xml"))
            )
            {
                // 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 );
            }
            else
            {
                bRet = Try3x(pStor, STREAM_READWRITE);
                if( !bRet )
                {
                    pStor->Remove(String::CreateFromAscii(pStarMathDoc));
                    bRet = Try2x(pStor, STREAM_READWRITE);
                    pStor->Remove(C2S("\1Ole10Native"));
                }
                else
                {
                    long nVersion = pStor->GetVersion();
                    if ( nVersion <= SOFFICE_FILEFORMAT_40 )
                        ConvertText( aText, CONVERT_40_TO_50 );
                    if ( nVersion <= SOFFICE_FILEFORMAT_50 )
                        ConvertText( aText, CONVERT_50_TO_60 );
                    if (pTree)
                    {
                        delete pTree;
                        pTree = NULL;
                    }
                }
            }
        }
    }
    FinishedLoading( SFX_LOADED_ALL );
    return bRet;
}

/*N*/ void SmDocShell::HandsOff()
/*N*/ {
/*N*/   SfxInPlaceObject::HandsOff();
/*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*/
/*N*/   SfxInPlaceObject::SetVisArea( aNewRect );
/*N*/
/*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->SetCryptMaskKey( 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*/
/*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':
                            {
                                rtl::OString aByteStr = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(*pSvStream);
/*N*/                           aText = ImportString( aByteStr );
/*N*/                           Parse();
                            }
/*N*/                       break;
/*N*/
/*N*/                   case 'D':
/*?*/                       aBuffer = pSvStream->ReadUniOrByteString(eEnc);
/*?*/                       aBuffer = pSvStream->ReadUniOrByteString(eEnc);
/*?*/                       *pSvStream >> lDate >> lTime;
/*?*/                       aBuffer = pSvStream->ReadUniOrByteString(eEnc);
/*?*/                       *pSvStream >> lDate >> lTime;
/*?*/                       aBuffer = pSvStream->ReadUniOrByteString(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*/                         USHORT      n;
/*N*/                         pSvStream->ReadUniOrByteString(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*/       }
/*N*/   }
/*N*/
/*N*/   if (!bRet)
/*N*/   {
/*N*/       // kein Passwort gesetzt --> Datei marode
/*?*/       if (pStor->GetKey().isEmpty())
/*?*/       {
/*?*/           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;

        *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':
                        {
                            rtl::OString aByteStr = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(*pSvStream);
                            aText = ImportString( aByteStr );
                            Parse();
                        }
                        break;

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

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

                    case 'S':
                    {
                        USHORT      n;
                        pSvStream->ReadUniOrByteString(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  = SmResId(STR_MATH_DOCUMENT_FULLTYPE_31).toString();
/*N*/       *pShortTypeName = SmResId(RID_DOCUMENTSTR).toString();
/*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  = SmResId(STR_MATH_DOCUMENT_FULLTYPE_40).toString();
/*N*/       *pShortTypeName = SmResId(RID_DOCUMENTSTR).toString();
/*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  = SmResId(STR_MATH_DOCUMENT_FULLTYPE_50).toString();
/*N*/       *pShortTypeName = SmResId(RID_DOCUMENTSTR).toString();
/*N*/   }
/*N*/   else if (nFileFormat == SOFFICE_FILEFORMAT_60 )
/*N*/   {
/*N*/       *pFullTypeName  = SmResId(STR_MATH_DOCUMENT_FULLTYPE_60).toString();
/*N*/       *pShortTypeName = SmResId(RID_DOCUMENTSTR).toString();

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




}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
