diff options
Diffstat (limited to 'starmath/source/document.cxx')
-rw-r--r-- | starmath/source/document.cxx | 1449 |
1 files changed, 1449 insertions, 0 deletions
diff --git a/starmath/source/document.cxx b/starmath/source/document.cxx new file mode 100644 index 000000000000..90da132a385a --- /dev/null +++ b/starmath/source/document.cxx @@ -0,0 +1,1449 @@ +/* -*- 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_starmath.hxx" + + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/uno/Any.h> + +#include <comphelper/accessibletexthelper.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/storagehelper.hxx> +#include <rtl/logfile.hxx> +#include <rtl/ustring.hxx> +#include <unotools/eventcfg.hxx> +#include <sfx2/event.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/fcontnr.hxx> +#include <sfx2/msg.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/printer.hxx> +#include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> +#include <sot/clsids.hxx> +#include <sot/exchange.hxx> +#include <sot/formats.hxx> +#include <sot/storage.hxx> +#include <svl/eitem.hxx> +#include <svl/fstathelper.hxx> +#include <svl/intitem.hxx> +#include <svl/itempool.hxx> +#include <unotools/lingucfg.hxx> +#include <unotools/linguprops.hxx> +#include <unotools/pathoptions.hxx> +#include <svl/ptitem.hxx> +#include <svtools/sfxecode.hxx> +#include <svl/slstitm.hxx> +#include <svl/smplhint.hxx> +#include <svl/stritem.hxx> +#include <svtools/transfer.hxx> +#include <svl/undo.hxx> +#include <svl/urihelper.hxx> +#include <svl/whiter.hxx> +#include <editeng/editeng.hxx> +#include <editeng/editstat.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/unolingu.hxx> +#include <ucbhelper/content.hxx> +#include <vcl/mapmod.hxx> +#include <tools/mapunit.hxx> +#include <vcl/msgbox.hxx> +#include <sfx2/sfx.hrc> +#include <document.hxx> +#include <action.hxx> +#include <config.hxx> +#include <dialog.hxx> +#include <format.hxx> +#include <smdll.hxx> +#include <starmath.hrc> +#include <symbol.hxx> +#include <toolbox.hxx> +#include <unomodel.hxx> +#include <utility.hxx> +#include <view.hxx> +#include "mathtype.hxx" +#include "ooxml.hxx" +#include "mathmlimport.hxx" +#include "mathmlexport.hxx" +#include <sfx2/sfxsids.hrc> +#include <svx/svxids.hrc> +#include "cursor.hxx" +#include <tools/diagnose_ex.h> +#include "visitors.hxx" +#include "accessibility.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::ucb; +using namespace ::com::sun::star::uno; + + +#define DOCUMENT_BUFFER_SIZE (sal_uInt16)32768 + +static const char pStarMathDoc[] = "StarMathDocument"; + +#define SmDocShell +#include "smslots.hxx" + +//////////////////////////////////////////////////////////// + + +TYPEINIT1( SmDocShell, SfxObjectShell ); + +SFX_IMPL_INTERFACE(SmDocShell, SfxObjectShell, SmResId(0)) +{ + SFX_POPUPMENU_REGISTRATION(SmResId(RID_VIEWMENU)); + SFX_POPUPMENU_REGISTRATION(SmResId(RID_COMMANDMENU)); +} + +SFX_IMPL_OBJECTFACTORY(SmDocShell, SvGlobalName(SO3_SM_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "smath" ) + +void SmDocShell::SFX_NOTIFY(SfxBroadcaster&, const TypeId&, + const SfxHint& rHint, const TypeId&) +{ + switch (((SfxSimpleHint&)rHint).GetId()) + { + case HINT_FORMATCHANGED: + SetFormulaArranged(false); + + nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState + + Repaint(); + break; + } +} + +void SmDocShell::LoadSymbols() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::LoadSymbols" ); + + SmModule *pp = SM_MOD(); + pp->GetSymbolManager().Load(); +} + + +const String SmDocShell::GetComment() const +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetComment" ); + uno::Reference<document::XDocumentPropertiesSupplier> xDPS( + const_cast<SmDocShell*>(this)->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<document::XDocumentProperties> xDocProps( + xDPS->getDocumentProperties()); + return xDocProps->getDescription(); +} + + +void SmDocShell::SetText(const String& rBuffer) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetText" ); + + if (rBuffer != aText) + { + bool bIsEnabled = IsEnableSetModified(); + if( bIsEnabled ) + EnableSetModified( false ); + + aText = rBuffer; + SetFormulaArranged( false ); + + Parse(); + + SmViewShell *pViewSh = SmGetActiveView(); + if( pViewSh ) + { + pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT); + if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) + { + // have SwOleClient::FormatChanged() to align the modified formula properly + // even if the vis area does not change (e.g. when formula text changes from + // "{a over b + c} over d" to "d over {a over b + c}" + SFX_APP()->NotifyEvent(SfxEventHint( SFX_EVENT_VISAREACHANGED, GlobalEventConfig::GetEventName(STR_EVENT_VISAREACHANGED), this)); + + Repaint(); + } + else + pViewSh->GetGraphicWindow().Invalidate(); + } + + if ( bIsEnabled ) + EnableSetModified( bIsEnabled ); + SetModified(true); + + // launch accessible event if necessary + SmGraphicAccessible *pAcc = pViewSh ? pViewSh->GetGraphicWindow().GetAccessible_Impl() : 0; + if (pAcc) + { + Any aOldValue, aNewValue; + if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( aText, rBuffer, aOldValue, aNewValue ) ) + { + pAcc->LaunchEvent( AccessibleEventId::TEXT_CHANGED, + aOldValue, aNewValue ); + } + } + + if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) + OnDocumentPrinterChanged(0); + } +} + +void SmDocShell::SetFormat(SmFormat& rFormat) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetFormat" ); + + aFormat = rFormat; + SetFormulaArranged( false ); + SetModified( true ); + + nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState + + // don't use SmGetActiveView since the view shell might not be active (0 pointer) + // if for example the Basic Macro dialog currently has the focus. Thus: + SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); + while (pFrm) + { + pFrm->GetBindings().Invalidate(SID_GAPHIC_SM); + pFrm = SfxViewFrame::GetNext( *pFrm, this ); + } +} + +String SmDocShell::GetAccessibleText() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetAccessibleText" ); + + if (!IsFormulaArranged()) + ArrangeFormula(); + if (0 == aAccText.Len()) + { + OSL_ENSURE( pTree, "Tree missing" ); + if (pTree) + pTree->GetAccessibleText( aAccText ); + } + return aAccText; +} + +void SmDocShell::Parse() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Parse" ); + + if (pTree) + delete pTree; + ReplaceBadChars(); + pTree = aInterpreter.Parse(aText); + nModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState + SetFormulaArranged( false ); + InvalidateCursor(); + aUsedSymbols = aInterpreter.GetUsedSymbols(); +} + + +void SmDocShell::ArrangeFormula() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ArrangeFormula" ); + + if (IsFormulaArranged()) + return; + + //! Nur f�r die Dauer der Existenz dieses Objekts sind am Drucker die + //! richtigen Einstellungen garantiert. + SmPrinterAccess aPrtAcc(*this); + OutputDevice* pOutDev = aPrtAcc.GetRefDev(); + + if (!pOutDev) + { +#if OSL_DEBUG_LEVEL > 1 + OSL_FAIL("!! SmDocShell::ArrangeFormula: reference device missing !!"); +#endif + } + + // falls n�tig ein anderes OutputDevice holen f�r das formatiert wird + if (!pOutDev) + { + SmViewShell *pView = SmGetActiveView(); + if (pView) + pOutDev = &pView->GetGraphicWindow(); + else + { + pOutDev = &SM_MOD()->GetDefaultVirtualDev(); + pOutDev->SetMapMode( MapMode(MAP_100TH_MM) ); + } + } + OSL_ENSURE(pOutDev->GetMapMode().GetMapUnit() == MAP_100TH_MM, + "Sm : falscher MapMode"); + + const SmFormat &rFormat = GetFormat(); + pTree->Prepare(rFormat, *this); + + // format/draw formulas always from left to right, + // and numbers should not be converted + sal_uLong nLayoutMode = pOutDev->GetLayoutMode(); + pOutDev->SetLayoutMode( TEXT_LAYOUT_BIDI_LTR ); + sal_Int16 nDigitLang = pOutDev->GetDigitLanguage(); + pOutDev->SetDigitLanguage( LANGUAGE_ENGLISH ); + // + pTree->Arrange(*pOutDev, rFormat); + // + pOutDev->SetLayoutMode( nLayoutMode ); + pOutDev->SetDigitLanguage( nDigitLang ); + + SetFormulaArranged(true); + + // invalidate accessible text + aAccText = String(); +} + + +void SetEditEngineDefaultFonts(SfxItemPool &rEditEngineItemPool) +{ + // + // set fonts to be used + // + SvtLinguOptions aOpt; + SvtLinguConfig().GetOptions( aOpt ); + // + struct FontDta { + sal_Int16 nFallbackLang; + sal_Int16 nLang; + sal_uInt16 nFontType; + sal_uInt16 nFontInfoId; + } aTable[3] = + { + // info to get western font to be used + { LANGUAGE_ENGLISH_US, LANGUAGE_NONE, + DEFAULTFONT_FIXED, EE_CHAR_FONTINFO }, + // info to get CJK font to be used + { LANGUAGE_JAPANESE, LANGUAGE_NONE, + DEFAULTFONT_CJK_TEXT, EE_CHAR_FONTINFO_CJK }, + // info to get CTL font to be used + { LANGUAGE_ARABIC_SAUDI_ARABIA, LANGUAGE_NONE, + DEFAULTFONT_CTL_TEXT, EE_CHAR_FONTINFO_CTL } + }; + aTable[0].nLang = aOpt.nDefaultLanguage; + aTable[1].nLang = aOpt.nDefaultLanguage_CJK; + aTable[2].nLang = aOpt.nDefaultLanguage_CTL; + // + for (int i = 0; i < 3; ++i) + { + const FontDta &rFntDta = aTable[i]; + LanguageType nLang = (LANGUAGE_NONE == rFntDta.nLang) ? + rFntDta.nFallbackLang : rFntDta.nLang; + Font aFont = Application::GetDefaultDevice()->GetDefaultFont( + rFntDta.nFontType, nLang, DEFAULTFONT_FLAGS_ONLYONE ); + rEditEngineItemPool.SetPoolDefaultItem( + SvxFontItem( aFont.GetFamily(), aFont.GetName(), + aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), + rFntDta.nFontInfoId ) ); + } + + // set font heights + SvxFontHeightItem aFontHeigt( + Application::GetDefaultDevice()->LogicToPixel( + Size( 0, 11 ), MapMode( MAP_POINT ) ).Height(), 100, + EE_CHAR_FONTHEIGHT ); + rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt ); + aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CJK ); + rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt ); + aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CTL ); + rEditEngineItemPool.SetPoolDefaultItem( aFontHeigt ); +} + + +EditEngine& SmDocShell::GetEditEngine() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngine" ); + + if (!pEditEngine) + { + //! + //! see also SmEditWindow::DataChanged ! + //! + + pEditEngineItemPool = EditEngine::CreatePool(); + + SetEditEngineDefaultFonts(*pEditEngineItemPool); + + pEditEngine = new EditEngine( pEditEngineItemPool ); + + pEditEngine->EnableUndo( true ); + pEditEngine->SetDefTab( sal_uInt16( + Application::GetDefaultDevice()->GetTextWidth( C2S("XXXX") ) ) ); + + pEditEngine->SetControlWord( + (pEditEngine->GetControlWord() | EE_CNTRL_AUTOINDENTING) & + (~EE_CNTRL_UNDOATTRIBS) & + (~EE_CNTRL_PASTESPECIAL) ); + + pEditEngine->SetWordDelimiters( C2S(" .=+-*/(){}[];\"" ) ); + pEditEngine->SetRefMapMode( MAP_PIXEL ); + + pEditEngine->SetPaperSize( Size( 800, 0 ) ); + + pEditEngine->EraseVirtualDevice(); + + // set initial text if the document already has some... + // (may be the case when reloading a doc) + String aTxt( GetText() ); + if (aTxt.Len()) + pEditEngine->SetText( aTxt ); + + pEditEngine->ClearModifyFlag(); + + } + return *pEditEngine; +} + + +SfxItemPool& SmDocShell::GetEditEngineItemPool() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetEditEngineItemPool" ); + + if (!pEditEngineItemPool) + GetEditEngine(); + OSL_ENSURE( pEditEngineItemPool, "EditEngineItemPool missing" ); + return *pEditEngineItemPool; +} + +void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" ); + + if (!pTree) + Parse(); + OSL_ENSURE(pTree, "Sm : NULL pointer"); + + if (!IsFormulaArranged()) + ArrangeFormula(); + + //Problem: Was passiert mit dem WYSIWYG? Wir haben waehrend wir inplace aktiv + //sind kein Referenzdevice und sind auch nicht darauf ausgerichtet. Es kann + //also jetzt eine Differenz zwischen der VisArea (spricht die Groesse im Client) + //und der jetzt vorliegenden Groese geben. + //Idee: Die Differenz koennte, zumindest behelfsmaessig, mit SmNod::SetSize + //angepasst werden. + + rPosition.X() += aFormat.GetDistance( DIS_LEFTSPACE ); + rPosition.Y() += aFormat.GetDistance( DIS_TOPSPACE ); + + //! in case of high contrast-mode (accessibility option!) + //! the draw mode needs to be set to default, because when imbedding + //! Math for example in Calc in "a over b" the fraction bar may not + //! be visible else. More generally: the FillColor may have been changed. + sal_uLong nOldDrawMode = DRAWMODE_DEFAULT; + bool bRestoreDrawMode = false; + if (OUTDEV_WINDOW == rDev.GetOutDevType() && + ((Window &) rDev).GetSettings().GetStyleSettings().GetHighContrastMode()) + { + nOldDrawMode = rDev.GetDrawMode(); + rDev.SetDrawMode( DRAWMODE_DEFAULT ); + bRestoreDrawMode = true; + } + + // format/draw formulas always from left to right + // and numbers should not be converted + sal_uLong nLayoutMode = rDev.GetLayoutMode(); + rDev.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR ); + sal_Int16 nDigitLang = rDev.GetDigitLanguage(); + rDev.SetDigitLanguage( LANGUAGE_ENGLISH ); + + //Set selection if any + if(pCursor && bDrawSelection){ + pCursor->AnnotateSelection(); + SmSelectionDrawingVisitor(rDev, pTree, rPosition); + } + + //Drawing using visitor + SmDrawingVisitor(rDev, rPosition, pTree); + + // + rDev.SetLayoutMode( nLayoutMode ); + rDev.SetDigitLanguage( nDigitLang ); + + if (bRestoreDrawMode) + rDev.SetDrawMode( nOldDrawMode ); +} + + + +Size SmDocShell::GetSize() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetSize" ); + + Size aRet; + + if (!pTree) + Parse(); + + if (pTree) + { + if (!IsFormulaArranged()) + ArrangeFormula(); + aRet = pTree->GetSize(); + + if ( !aRet.Width() ) + aRet.Width() = 2000; + else + aRet.Width() += aFormat.GetDistance( DIS_LEFTSPACE ) + + aFormat.GetDistance( DIS_RIGHTSPACE ); + if ( !aRet.Height() ) + aRet.Height() = 1000; + else + aRet.Height() += aFormat.GetDistance( DIS_TOPSPACE ) + + aFormat.GetDistance( DIS_BOTTOMSPACE ); + } + + return aRet; +} + +void SmDocShell::InvalidateCursor(){ + delete pCursor; + pCursor = NULL; +} + +SmCursor& SmDocShell::GetCursor(){ + if(!pCursor) + pCursor = new SmCursor(pTree, this); + return *pCursor; +} + +//////////////////////////////////////// + +SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell ) +{ + if ( 0 != (pPrinter = rDocShell.GetPrt()) ) + { + pPrinter->Push( PUSH_MAPMODE ); + if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() ) + { + // if it is an embedded object (without it's own printer) + // we change the MapMode temporarily. + //!If it is a document with it's own printer the MapMode should + //!be set correct (once) elsewhere(!), in order to avoid numerous + //!superfluous pushing and poping of the MapMode when using + //!this class. + + 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 ); + } + } + } + if ( 0 != (pRefDev = rDocShell.GetRefDev()) && pPrinter != pRefDev ) + { + pRefDev->Push( PUSH_MAPMODE ); + if ( SFX_CREATE_MODE_EMBEDDED == rDocShell.GetCreateMode() ) + { + // if it is an embedded object (without it's own printer) + // we change the MapMode temporarily. + //!If it is a document with it's own printer the MapMode should + //!be set correct (once) elsewhere(!), in order to avoid numerous + //!superfluous pushing and poping of the MapMode when using + //!this class. + + const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit(); + if ( MAP_100TH_MM != eOld ) + { + MapMode aMap( pRefDev->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 ); + pRefDev->SetMapMode( aMap ); + } + } + } +} + +SmPrinterAccess::~SmPrinterAccess() +{ + if ( pPrinter ) + pPrinter->Pop(); + if ( pRefDev && pRefDev != pPrinter ) + pRefDev->Pop(); +} + +//////////////////////////////////////// + +Printer* SmDocShell::GetPrt() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetPrt" ); + + if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) + { + //Normalerweise wird der Printer vom Server besorgt. Wenn dieser aber + //keinen liefert (weil etwa noch keine connection da ist), kann es + //dennoch sein, dass wir den Printer kennen, denn dieser wird in + //OnDocumentPrinterChanged vom Server durchgereicht und dann temporaer + //festgehalten. + Printer *pPrt = GetDocumentPrinter(); + if ( !pPrt && pTmpPrinter ) + pPrt = pTmpPrinter; + return pPrt; + } + else if ( !pPrinter ) + { + SfxItemSet *pOptions = + new SfxItemSet(GetPool(), + SID_PRINTSIZE, SID_PRINTSIZE, + SID_PRINTZOOM, SID_PRINTZOOM, + SID_PRINTTITLE, SID_PRINTTITLE, + SID_PRINTTEXT, SID_PRINTTEXT, + SID_PRINTFRAME, SID_PRINTFRAME, + SID_NO_RIGHT_SPACES, SID_NO_RIGHT_SPACES, + 0); + + SmModule *pp = SM_MOD(); + pp->GetConfig()->ConfigToItemSet(*pOptions); + pPrinter = new SfxPrinter(pOptions); + pPrinter->SetMapMode( MapMode(MAP_100TH_MM) ); + } + return pPrinter; +} + +OutputDevice* SmDocShell::GetRefDev() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetRefDev" ); + + if ( SFX_CREATE_MODE_EMBEDDED == GetCreateMode() ) + { + OutputDevice* pOutDev = GetDocumentRefDev(); + if ( pOutDev ) + return pOutDev; + } + + return GetPrt(); +} + + +void SmDocShell::SetPrinter( SfxPrinter *pNew ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetPrinter" ); + + delete pPrinter; + pPrinter = pNew; //Eigentumsuebergang! + pPrinter->SetMapMode( MapMode(MAP_100TH_MM) ); + SetFormulaArranged(false); + Repaint(); +} + +void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::OnDocumentPrinterChanged" ); + + pTmpPrinter = pPrt; + SetFormulaArranged(false); + Size aOldSize = GetVisArea().GetSize(); + Repaint(); + if( aOldSize != GetVisArea().GetSize() && aText.Len() ) + SetModified( true ); + pTmpPrinter = 0; +} + +void SmDocShell::Repaint() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Repaint" ); + + bool bIsEnabled = IsEnableSetModified(); + if ( bIsEnabled ) + EnableSetModified( false ); + + SetFormulaArranged( false ); + + Size aVisSize = GetSize(); + SetVisAreaSize( aVisSize ); + SmViewShell *pViewSh = SmGetActiveView(); + if (pViewSh) + pViewSh->GetGraphicWindow().Invalidate(); + + if ( bIsEnabled ) + EnableSetModified( bIsEnabled ); +} + + +SmDocShell::SmDocShell( const sal_uInt64 i_nSfxCreationFlags ) : + SfxObjectShell( i_nSfxCreationFlags ), + pTree ( 0 ), + pEditEngineItemPool ( 0 ), + pEditEngine ( 0 ), + pPrinter ( 0 ), + pTmpPrinter ( 0 ), + nModifyCount ( 0 ), + bIsFormulaArranged ( false ) +{ + pCursor = NULL; + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SmDocShell" ); + + SetPool(&SFX_APP()->GetPool()); + + SmModule *pp = SM_MOD(); + aFormat = pp->GetConfig()->GetStandardFormat(); + + StartListening(aFormat); + StartListening(*pp->GetConfig()); + + SetBaseModel( new SmModel(this) ); +} + + + +SmDocShell::~SmDocShell() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::~SmDocShell" ); + + SmModule *pp = SM_MOD(); + + EndListening(aFormat); + EndListening(*pp->GetConfig()); + + + if(pCursor) + delete pCursor; + pCursor = NULL; + + delete pEditEngine; + SfxItemPool::Free(pEditEngineItemPool); + delete pTree; + delete pPrinter; +} + + +sal_Bool SmDocShell::SetData( const String& rData ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetData" ); + + SetText( rData ); + return true; +} + + +sal_Bool SmDocShell::ConvertFrom(SfxMedium &rMedium) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertFrom" ); + + bool bSuccess = false; + const String& rFltName = rMedium.GetFilter()->GetFilterName(); + + OSL_ENSURE( !rFltName.EqualsAscii( STAROFFICE_XML ), "Wrong filter!"); + + if ( rFltName.EqualsAscii( MATHML_XML ) ) + { + if (pTree) + { + delete pTree; + pTree = 0; + InvalidateCursor(); + } + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLImportWrapper aEquation(xModel); + bSuccess = 0 == aEquation.Import(rMedium); + } + else + { + SvStream *pStream = rMedium.GetInStream(); + if ( pStream ) + { + if ( SotStorage::IsStorageFile( pStream ) ) + { + SvStorageRef aStorage = new SotStorage( pStream, false ); + if ( aStorage->IsStream( C2S( "Equation Native" ) ) ) + { + // is this a MathType Storage? + MathType aEquation( aText ); + if ( true == (bSuccess = (1 == aEquation.Parse( aStorage )) )) + Parse(); + } + } + } + } + + if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) + { + SetFormulaArranged( false ); + Repaint(); + } + + FinishedLoading( SFX_LOADED_ALL ); + return bSuccess; +} + + +sal_Bool SmDocShell::InitNew( const uno::Reference < embed::XStorage >& xStorage ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::InitNew" ); + + bool bRet = false; + if ( SfxObjectShell::InitNew( xStorage ) ) + { + bRet = true; + SetVisArea(Rectangle(Point(0, 0), Size(2000, 1000))); + } + return bRet; +} + + +sal_Bool SmDocShell::Load( SfxMedium& rMedium ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Load" ); + + bool bRet = false; + if( SfxObjectShell::Load( rMedium )) + { + uno::Reference < embed::XStorage > xStorage = GetMedium()->GetStorage(); + uno::Reference < container::XNameAccess > xAccess (xStorage, uno::UNO_QUERY); + if ( + ( + xAccess->hasByName( C2S( "content.xml" ) ) && + xStorage->isStreamElement( C2S( "content.xml" ) ) + ) || + ( + xAccess->hasByName( C2S( "Content.xml" ) ) && + xStorage->isStreamElement( C2S( "Content.xml" ) ) + ) + ) + { + // is this a fabulous math package ? + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLImportWrapper aEquation(xModel); + sal_uLong nError = aEquation.Import(rMedium); + bRet = 0 == nError; + SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); + } + } + + if ( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED ) + { + SetFormulaArranged( false ); + Repaint(); + } + + FinishedLoading( SFX_LOADED_ALL ); + return bRet; +} + +//------------------------------------------------------------------ + +sal_Bool SmDocShell::Save() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Save" ); + + //! apply latest changes if necessary + UpdateText(); + + if ( SfxObjectShell::Save() ) + { + if (!pTree) + Parse(); + if( pTree && !IsFormulaArranged() ) + ArrangeFormula(); + + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLExportWrapper aEquation(xModel); + aEquation.SetFlat(sal_False); + return aEquation.Export(*GetMedium()); + } + + return false; +} + +/* + * replace bad characters that can not be saved. (#i74144) + * */ +sal_Bool SmDocShell::ReplaceBadChars() +{ + sal_Bool bReplace = sal_False; + if (pEditEngine) + { + String aEngTxt( pEditEngine->GetText( LINEEND_LF ) ); + const sal_Unicode *pEngTxt = aEngTxt.GetBuffer(); + xub_StrLen nLen = aEngTxt.Len(); + for (xub_StrLen i = 0; i < nLen && !bReplace; ++i) + { + const sal_Unicode c = *pEngTxt++; + if (c < ' ' && c != '\r' && c != '\n' && c != '\t') + bReplace = sal_True; + } + if (bReplace) + { + sal_Unicode *pChgTxt = aEngTxt.GetBufferAccess(); + for (xub_StrLen i = 0; i < nLen; ++i) + { + sal_Unicode &rc = *pChgTxt++; + if (rc < ' ' && rc != '\r' && rc != '\n' && rc != '\t') + rc = ' '; + } + aEngTxt.ReleaseBufferAccess( nLen ); + + aText = aEngTxt; + } + } + return bReplace; +} + + +void SmDocShell::UpdateText() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::UpdateText" ); + + if (pEditEngine && pEditEngine->IsModified()) + { + String aEngTxt( pEditEngine->GetText( LINEEND_LF ) ); + if (GetText() != aEngTxt) + SetText( aEngTxt ); + } +} + + +sal_Bool SmDocShell::SaveAs( SfxMedium& rMedium ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveAs" ); + + bool bRet = false; + + //! apply latest changes if necessary + UpdateText(); + + if ( SfxObjectShell::SaveAs( rMedium ) ) + { + if (!pTree) + Parse(); + if( pTree && !IsFormulaArranged() ) + ArrangeFormula(); + + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLExportWrapper aEquation(xModel); + aEquation.SetFlat(sal_False); + bRet = aEquation.Export(rMedium); + } + return bRet; +} + +sal_Bool SmDocShell::ConvertTo( SfxMedium &rMedium ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::ConvertTo" ); + + bool bRet = false; + const SfxFilter* pFlt = rMedium.GetFilter(); + if( pFlt ) + { + if( !pTree ) + Parse(); + if( pTree && !IsFormulaArranged() ) + ArrangeFormula(); + + const String& rFltName = pFlt->GetFilterName(); + if(rFltName.EqualsAscii( STAROFFICE_XML )) + { + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLExportWrapper aEquation(xModel); + aEquation.SetFlat(sal_False); + bRet = aEquation.Export(rMedium); + } + else if(rFltName.EqualsAscii( MATHML_XML )) + { + Reference<com::sun::star::frame::XModel> xModel(GetModel()); + SmXMLExportWrapper aEquation(xModel); + aEquation.SetFlat(sal_True); + bRet = aEquation.Export(rMedium); + } + else if( pFlt->GetFilterName().EqualsAscii("MathType 3.x")) + bRet = WriteAsMathType3( rMedium ); + } + return bRet; +} + +bool SmDocShell::writeFormulaOoxml( ::sax_fastparser::FSHelperPtr m_pSerializer, oox::core::OoxmlVersion version ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::writeFormulaOoxml" ); + + if( !pTree ) + Parse(); + if( pTree && !IsFormulaArranged() ) + ArrangeFormula(); + SmOoxml aEquation( aText, pTree, version ); + return aEquation.ConvertFromStarMath( m_pSerializer ); +} + +sal_Bool SmDocShell::SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveCompleted" ); + + if( SfxObjectShell::SaveCompleted( xStorage )) + return true; + + return false; +} + + +void SmDocShell::Execute(SfxRequest& rReq) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Execute" ); + + switch (rReq.GetSlot()) + { + case SID_TEXTMODE: + { + SmFormat aOldFormat = GetFormat(); + SmFormat aNewFormat( aOldFormat ); + aNewFormat.SetTextmode(!aOldFormat.IsTextmode()); + + ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); + if (pTmpUndoMgr) + pTmpUndoMgr->AddUndoAction( + new SmFormatAction(this, aOldFormat, aNewFormat)); + + SetFormat( aNewFormat ); + Repaint(); + } + break; + + case SID_AUTO_REDRAW : + { + SmModule *pp = SM_MOD(); + bool bRedraw = pp->GetConfig()->IsAutoRedraw(); + pp->GetConfig()->SetAutoRedraw(!bRedraw); + } + break; + + case SID_LOADSYMBOLS: + LoadSymbols(); + break; + + case SID_SAVESYMBOLS: + SaveSymbols(); + break; + + case SID_FONT: + { + // get device used to retrieve the FontList + OutputDevice *pDev = GetPrinter(); + if (!pDev || pDev->GetDevFontCount() == 0) + pDev = &SM_MOD()->GetDefaultVirtualDev(); + OSL_ENSURE (pDev, "device for font list missing" ); + + SmFontTypeDialog *pFontTypeDialog = new SmFontTypeDialog( NULL, pDev ); + + SmFormat aOldFormat = GetFormat(); + pFontTypeDialog->ReadFrom( aOldFormat ); + if (pFontTypeDialog->Execute() == RET_OK) + { + SmFormat aNewFormat( aOldFormat ); + + pFontTypeDialog->WriteTo(aNewFormat); + ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); + if (pTmpUndoMgr) + pTmpUndoMgr->AddUndoAction( + new SmFormatAction(this, aOldFormat, aNewFormat)); + + SetFormat( aNewFormat ); + Repaint(); + } + delete pFontTypeDialog; + } + break; + + case SID_FONTSIZE: + { + SmFontSizeDialog *pFontSizeDialog = new SmFontSizeDialog(NULL); + + SmFormat aOldFormat = GetFormat(); + pFontSizeDialog->ReadFrom( aOldFormat ); + if (pFontSizeDialog->Execute() == RET_OK) + { + SmFormat aNewFormat( aOldFormat ); + + pFontSizeDialog->WriteTo(aNewFormat); + + ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); + if (pTmpUndoMgr) + pTmpUndoMgr->AddUndoAction( + new SmFormatAction(this, aOldFormat, aNewFormat)); + + SetFormat( aNewFormat ); + Repaint(); + } + delete pFontSizeDialog; + } + break; + + case SID_DISTANCE: + { + SmDistanceDialog *pDistanceDialog = new SmDistanceDialog(NULL); + + SmFormat aOldFormat = GetFormat(); + pDistanceDialog->ReadFrom( aOldFormat ); + if (pDistanceDialog->Execute() == RET_OK) + { + SmFormat aNewFormat( aOldFormat ); + + pDistanceDialog->WriteTo(aNewFormat); + + ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); + if (pTmpUndoMgr) + pTmpUndoMgr->AddUndoAction( + new SmFormatAction(this, aOldFormat, aNewFormat)); + + SetFormat( aNewFormat ); + Repaint(); + } + delete pDistanceDialog; + } + break; + + case SID_ALIGN: + { + SmAlignDialog *pAlignDialog = new SmAlignDialog(NULL); + + SmFormat aOldFormat = GetFormat(); + pAlignDialog->ReadFrom( aOldFormat ); + if (pAlignDialog->Execute() == RET_OK) + { + SmFormat aNewFormat( aOldFormat ); + + pAlignDialog->WriteTo(aNewFormat); + + SmModule *pp = SM_MOD(); + SmFormat aFmt( pp->GetConfig()->GetStandardFormat() ); + pAlignDialog->WriteTo( aFmt ); + pp->GetConfig()->SetStandardFormat( aFmt ); + + ::svl::IUndoManager *pTmpUndoMgr = GetUndoManager(); + if (pTmpUndoMgr) + pTmpUndoMgr->AddUndoAction( + new SmFormatAction(this, aOldFormat, aNewFormat)); + + SetFormat( aNewFormat ); + Repaint(); + } + delete pAlignDialog; + } + break; + + case SID_TEXT: + { + const SfxStringItem& rItem = (const SfxStringItem&)rReq.GetArgs()->Get(SID_TEXT); + if (GetText() != rItem.GetValue()) + SetText(rItem.GetValue()); + } + break; + + case SID_UNDO: + case SID_REDO: + { + ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager(); + if( pTmpUndoMgr ) + { + sal_uInt16 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(); + + sal_Bool (::svl::IUndoManager:: *fnDo)(); + + sal_uInt16 nCount; + if( SID_UNDO == rReq.GetSlot() ) + { + nCount = pTmpUndoMgr->GetUndoActionCount(); + fnDo = &::svl::IUndoManager::Undo; + } + else + { + nCount = pTmpUndoMgr->GetRedoActionCount(); + fnDo = &::svl::IUndoManager::Redo; + } + + try + { + for( ; nCnt && nCount; --nCnt, --nCount ) + (pTmpUndoMgr->*fnDo)(); + } + catch( const Exception& e ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + Repaint(); + UpdateText(); + SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); + while( pFrm ) + { + SfxBindings& rBind = pFrm->GetBindings(); + rBind.Invalidate(SID_UNDO); + rBind.Invalidate(SID_REDO); + rBind.Invalidate(SID_REPEAT); + rBind.Invalidate(SID_CLEARHISTORY); + pFrm = SfxViewFrame::GetNext( *pFrm, this ); + } + } + break; + } + + rReq.Done(); +} + + +void SmDocShell::GetState(SfxItemSet &rSet) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetState" ); + + SfxWhichIter aIter(rSet); + + for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich()) + { + switch (nWh) + { + 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_MOD(); + bool bRedraw = pp->GetConfig()->IsAutoRedraw(); + + rSet.Put(SfxBoolItem(SID_AUTO_REDRAW, bRedraw)); + } + break; + + case SID_MODIFYSTATUS: + { + sal_Unicode cMod = ' '; + if (IsModified()) + cMod = '*'; + rSet.Put(SfxStringItem(SID_MODIFYSTATUS, String(cMod))); + } + break; + + case SID_TEXT: + rSet.Put(SfxStringItem(SID_TEXT, GetText())); + break; + + case SID_GAPHIC_SM: + //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow. + //! If nModifyCount gets changed then the call below will implicitly notify + //! SmGraphicController::StateChanged and there the window gets invalidated. + //! Thus all the 'nModifyCount++' before invalidating this slot. + rSet.Put(SfxInt16Item(SID_GAPHIC_SM, nModifyCount)); + break; + + case SID_UNDO: + case SID_REDO: + { + SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); + if( pFrm ) + pFrm->GetSlotState( nWh, NULL, &rSet ); + else + rSet.DisableItem( nWh ); + } + break; + + case SID_GETUNDOSTRINGS: + case SID_GETREDOSTRINGS: + { + ::svl::IUndoManager* pTmpUndoMgr = GetUndoManager(); + if( pTmpUndoMgr ) + { + UniString(::svl::IUndoManager:: *fnGetComment)( size_t, bool const ) const; + + sal_uInt16 nCount; + if( SID_GETUNDOSTRINGS == nWh ) + { + nCount = pTmpUndoMgr->GetUndoActionCount(); + fnGetComment = &::svl::IUndoManager::GetUndoActionComment; + } + else + { + nCount = pTmpUndoMgr->GetRedoActionCount(); + fnGetComment = &::svl::IUndoManager::GetRedoActionComment; + } + if( nCount ) + { + String sList; + for( sal_uInt16 n = 0; n < nCount; ++n ) + ( sList += (pTmpUndoMgr->*fnGetComment)( n, ::svl::IUndoManager::TopLevel ) ) + += '\n'; + + SfxStringListItem aItem( nWh ); + aItem.SetString( sList ); + rSet.Put( aItem ); + } + } + else + rSet.DisableItem( nWh ); + } + break; + } + } +} + + +::svl::IUndoManager *SmDocShell::GetUndoManager() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::GetUndoManager" ); + + if (!pEditEngine) + GetEditEngine(); + return &pEditEngine->GetUndoManager(); +} + + +void SmDocShell::SaveSymbols() +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SaveSymbols" ); + + SmModule *pp = SM_MOD(); + pp->GetSymbolManager().Save(); +} + + +void SmDocShell::Draw(OutputDevice *pDevice, + const JobSetup &, + sal_uInt16 /*nAspect*/) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::Draw" ); + + pDevice->IntersectClipRegion(GetVisArea()); + Point atmppoint; + DrawFormula(*pDevice, atmppoint); +} + +SfxItemPool& SmDocShell::GetPool() const +{ + return SFX_APP()->GetPool(); +} + +void SmDocShell::SetVisArea(const Rectangle & rVisArea) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetVisArea" ); + + Rectangle aNewRect(rVisArea); + + aNewRect.SetPos(Point()); + + if (! aNewRect.Right()) aNewRect.Right() = 2000; + if (! aNewRect.Bottom()) aNewRect.Bottom() = 1000; + + bool bIsEnabled = IsEnableSetModified(); + if ( bIsEnabled ) + EnableSetModified( false ); + + //TODO/LATER: it's unclear how this interacts with the SFX code + // If outplace editing, then dont resize the OutplaceWindow. But the + // ObjectShell has to resize. Bug 56470 + bool bUnLockFrame; + if( GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !IsInPlaceActive() && GetFrame() ) + { + GetFrame()->LockAdjustPosSizePixel(); + bUnLockFrame = true; + } + else + bUnLockFrame = false; + + SfxObjectShell::SetVisArea( aNewRect ); + + if( bUnLockFrame ) + GetFrame()->UnlockAdjustPosSizePixel(); + + if ( bIsEnabled ) + EnableSetModified( bIsEnabled ); +} + + +void SmDocShell::FillClass(SvGlobalName* pClassName, + sal_uInt32* pFormat, + String* /*pAppName*/, + String* pFullTypeName, + String* pShortTypeName, + sal_Int32 nFileFormat, + sal_Bool bTemplate /* = sal_False */) const +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::FillClass" ); + + if (nFileFormat == SOFFICE_FILEFORMAT_60 ) + { + *pClassName = SvGlobalName(SO3_SM_CLASSID_60); + *pFormat = SOT_FORMATSTR_ID_STARMATH_60; + *pFullTypeName = String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT)); + *pShortTypeName = String(SmResId(RID_DOCUMENTSTR)); + } + else if (nFileFormat == SOFFICE_FILEFORMAT_8 ) + { + *pClassName = SvGlobalName(SO3_SM_CLASSID_60); + *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARMATH_8_TEMPLATE : SOT_FORMATSTR_ID_STARMATH_8; + *pFullTypeName = String(SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENT)); + *pShortTypeName = String(SmResId(RID_DOCUMENTSTR)); + } +} + +sal_uLong SmDocShell::GetMiscStatus() const +{ + return SfxObjectShell::GetMiscStatus() | SVOBJ_MISCSTATUS_NOTRESIZEABLE + | SVOBJ_MISCSTATUS_RESIZEONPRINTERCHANGE; +} + +void SmDocShell::SetModified(sal_Bool bModified) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::SetModified" ); + + if( IsEnableSetModified() ) + { + SfxObjectShell::SetModified( bModified ); + Broadcast(SfxSimpleHint(SFX_HINT_DOCCHANGED)); + } +} + +bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium ) +{ + RTL_LOGFILE_CONTEXT( aLog, "starmath: SmDocShell::WriteAsMathType3" ); + + MathType aEquation( aText, pTree ); + + bool bRet = 0 != aEquation.ConvertFromStarMath( rMedium ); + return bRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |