2009-05-19 09:31:27 +00:00
/*************************************************************************
*
2010-02-12 15:01:35 +01:00
* 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 .
*
2009-05-19 09:31:27 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// MARKER(update_precomp.py): autogen include statement, do not remove
# include "precompiled_starmath.hxx"
/*
Warning : The SvXMLElementExport helper class creates the beginning and
closing tags of xml elements in its constructor and destructor , so theres
hidden stuff going on , on occasion the ordering of these classes declarations
may be significant
*/
# include <com/sun/star/xml/sax/XErrorHandler.hpp>
# include <com/sun/star/xml/sax/XEntityResolver.hpp>
# include <com/sun/star/xml/sax/InputSource.hpp>
# include <com/sun/star/xml/sax/XDTDHandler.hpp>
# include <com/sun/star/xml/sax/XParser.hpp>
# include <com/sun/star/io/XActiveDataSource.hpp>
# include <com/sun/star/io/XActiveDataControl.hpp>
# include <com/sun/star/document/XDocumentProperties.hpp>
# include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
# include <com/sun/star/packages/zip/ZipIOException.hpp>
# include <com/sun/star/task/XStatusIndicatorFactory.hpp>
# include <com/sun/star/beans/PropertyAttribute.hpp>
# include <com/sun/star/container/XNameAccess.hpp>
# include <com/sun/star/embed/ElementModes.hpp>
# include <com/sun/star/uno/Any.h>
# include <rtl/math.hxx>
# include <sfx2/frame.hxx>
# include <sfx2/docfile.hxx>
# include <tools/debug.hxx>
# include <tools/urlobj.hxx>
# include <svtools/sfxecode.hxx>
2009-10-06 07:38:24 +02:00
# include <unotools/saveopt.hxx>
2009-10-16 00:05:16 +02:00
# include <svl/stritem.hxx>
# include <svl/itemprop.hxx>
2009-05-19 09:31:27 +00:00
# include <unotools/processfactory.hxx>
# include <unotools/streamwrap.hxx>
# include <xmloff/xmlnmspe.hxx>
# include <xmloff/xmltoken.hxx>
# include <xmloff/nmspmap.hxx>
# include <xmloff/attrlist.hxx>
# include <xmloff/xmluconv.hxx>
# include <xmloff/xmlmetai.hxx>
# include <osl/mutex.hxx>
# include <comphelper/genericpropertyset.hxx>
# include <memory>
# include "mathmlexport.hxx"
# include "mathtype.hxx"
# include <starmath.hrc>
# include <unomodel.hxx>
# include <document.hxx>
# include <utility.hxx>
using namespace : : com : : sun : : star : : beans ;
using namespace : : com : : sun : : star : : container ;
using namespace : : com : : sun : : star : : document ;
using namespace : : com : : sun : : star : : lang ;
using namespace : : com : : sun : : star : : uno ;
using namespace : : com : : sun : : star ;
using namespace : : xmloff : : token ;
using : : rtl : : OUString ;
using : : rtl : : OUStringBuffer ;
# define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
# undef WANTEXCEPT
////////////////////////////////////////////////////////////
sal_Bool SmXMLExportWrapper : : Export ( SfxMedium & rMedium )
{
sal_Bool bRet = sal_True ;
uno : : Reference < lang : : XMultiServiceFactory >
xServiceFactory ( utl : : getProcessServiceFactory ( ) ) ;
DBG_ASSERT ( xServiceFactory . is ( ) , " got no service manager " ) ;
//Get model
uno : : Reference < lang : : XComponent > xModelComp ( xModel , uno : : UNO_QUERY ) ;
sal_Bool bEmbedded = sal_False ;
uno : : Reference < lang : : XUnoTunnel > xTunnel ;
xTunnel = uno : : Reference < lang : : XUnoTunnel > ( xModel , uno : : UNO_QUERY ) ;
SmModel * pModel = reinterpret_cast < SmModel * >
( xTunnel - > getSomething ( SmModel : : getUnoTunnelId ( ) ) ) ;
SmDocShell * pDocShell = pModel ?
static_cast < SmDocShell * > ( pModel - > GetObjectShell ( ) ) : 0 ;
if ( pDocShell & &
SFX_CREATE_MODE_EMBEDDED = = pDocShell - > GetCreateMode ( ) )
bEmbedded = sal_True ;
uno : : Reference < task : : XStatusIndicator > xStatusIndicator ;
if ( ! bEmbedded )
{
if ( pDocShell /*&& pDocShell->GetMedium()*/ )
{
DBG_ASSERT ( pDocShell - > GetMedium ( ) = = & rMedium ,
" different SfxMedium found " ) ;
SfxItemSet * pSet = rMedium . GetItemSet ( ) ;
if ( pSet )
{
const SfxUnoAnyItem * pItem = static_cast < const SfxUnoAnyItem * > (
pSet - > GetItem ( SID_PROGRESS_STATUSBAR_CONTROL ) ) ;
if ( pItem )
pItem - > GetValue ( ) > > = xStatusIndicator ;
}
}
// set progress range and start status indicator
if ( xStatusIndicator . is ( ) )
{
sal_Int32 nProgressRange = bFlat ? 1 : 3 ;
xStatusIndicator - > start ( String ( SmResId ( STR_STATSTR_WRITING ) ) ,
nProgressRange ) ;
}
}
// create XPropertySet with three properties for status indicator
comphelper : : PropertyMapEntry aInfoMap [ ] =
{
{ " UsePrettyPrinting " , sizeof ( " UsePrettyPrinting " ) - 1 , 0 ,
& : : getBooleanCppuType ( ) ,
beans : : PropertyAttribute : : MAYBEVOID , 0 } ,
{ " BaseURI " , sizeof ( " BaseURI " ) - 1 , 0 ,
& : : getCppuType ( ( OUString * ) 0 ) ,
beans : : PropertyAttribute : : MAYBEVOID , 0 } ,
{ " StreamRelPath " , sizeof ( " StreamRelPath " ) - 1 , 0 ,
& : : getCppuType ( ( OUString * ) 0 ) ,
beans : : PropertyAttribute : : MAYBEVOID , 0 } ,
{ " StreamName " , sizeof ( " StreamName " ) - 1 , 0 ,
& : : getCppuType ( ( OUString * ) 0 ) ,
beans : : PropertyAttribute : : MAYBEVOID , 0 } ,
{ NULL , 0 , 0 , NULL , 0 , 0 }
} ;
uno : : Reference < beans : : XPropertySet > xInfoSet (
comphelper : : GenericPropertySet_CreateInstance (
new comphelper : : PropertySetInfo ( aInfoMap ) ) ) ;
SvtSaveOptions aSaveOpt ;
OUString sUsePrettyPrinting ( RTL_CONSTASCII_USTRINGPARAM ( " UsePrettyPrinting " ) ) ;
sal_Bool bUsePrettyPrinting ( bFlat | | aSaveOpt . IsPrettyPrinting ( ) ) ;
Any aAny ;
aAny . setValue ( & bUsePrettyPrinting , : : getBooleanCppuType ( ) ) ;
xInfoSet - > setPropertyValue ( sUsePrettyPrinting , aAny ) ;
// Set base URI
OUString sPropName ( RTL_CONSTASCII_USTRINGPARAM ( " BaseURI " ) ) ;
xInfoSet - > setPropertyValue ( sPropName , makeAny ( rMedium . GetBaseURL ( true ) ) ) ;
sal_Int32 nSteps = 0 ;
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > setValue ( nSteps + + ) ;
if ( ! bFlat ) //Storage (Package) of Stream
{
uno : : Reference < embed : : XStorage > xStg = rMedium . GetOutputStorage ( ) ;
sal_Bool bOASIS = ( SotStorage : : GetVersion ( xStg ) > SOFFICE_FILEFORMAT_60 ) ;
// TODO/LATER: handle the case of embedded links gracefully
if ( bEmbedded ) //&& !pStg->IsRoot() )
{
OUString aName ;
if ( rMedium . GetItemSet ( ) )
{
const SfxStringItem * pDocHierarchItem = static_cast < const SfxStringItem * > (
rMedium . GetItemSet ( ) - > GetItem ( SID_DOC_HIERARCHICALNAME ) ) ;
if ( pDocHierarchItem )
aName = pDocHierarchItem - > GetValue ( ) ;
}
if ( aName . getLength ( ) )
{
sPropName = OUString ( RTL_CONSTASCII_USTRINGPARAM ( " StreamRelPath " ) ) ;
xInfoSet - > setPropertyValue ( sPropName , makeAny ( aName ) ) ;
}
}
if ( ! bEmbedded )
{
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > setValue ( nSteps + + ) ;
bRet = WriteThroughComponent (
xStg , xModelComp , " meta.xml " , xServiceFactory , xInfoSet ,
( bOASIS ? " com.sun.star.comp.Math.XMLOasisMetaExporter "
: " com.sun.star.comp.Math.XMLMetaExporter " ) ,
sal_False ) ;
}
if ( bRet )
{
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > setValue ( nSteps + + ) ;
bRet = WriteThroughComponent (
xStg , xModelComp , " content.xml " , xServiceFactory , xInfoSet ,
" com.sun.star.comp.Math.XMLContentExporter " ) ;
}
if ( bRet )
{
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > setValue ( nSteps + + ) ;
bRet = WriteThroughComponent (
xStg , xModelComp , " settings.xml " , xServiceFactory , xInfoSet ,
( bOASIS ? " com.sun.star.comp.Math.XMLOasisSettingsExporter "
: " com.sun.star.comp.Math.XMLSettingsExporter " ) ) ;
}
}
else
{
SvStream * pStream = rMedium . GetOutStream ( ) ;
uno : : Reference < io : : XOutputStream > xOut (
new utl : : OOutputStreamWrapper ( * pStream ) ) ;
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > setValue ( nSteps + + ) ;
bRet = WriteThroughComponent (
xOut , xModelComp , xServiceFactory , xInfoSet ,
" com.sun.star.comp.Math.XMLContentExporter " ) ;
}
if ( xStatusIndicator . is ( ) )
xStatusIndicator - > end ( ) ;
return bRet ;
}
/// export through an XML exporter component (output stream version)
sal_Bool SmXMLExportWrapper : : WriteThroughComponent (
Reference < io : : XOutputStream > xOutputStream ,
Reference < XComponent > xComponent ,
Reference < lang : : XMultiServiceFactory > & rFactory ,
Reference < beans : : XPropertySet > & rPropSet ,
const sal_Char * pComponentName )
{
DBG_ASSERT ( xOutputStream . is ( ) , " I really need an output stream! " ) ;
DBG_ASSERT ( xComponent . is ( ) , " Need component! " ) ;
DBG_ASSERT ( NULL ! = pComponentName , " Need component name! " ) ;
// get component
Reference < io : : XActiveDataSource > xSaxWriter (
rFactory - > createInstance (
OUString : : createFromAscii ( " com.sun.star.xml.sax.Writer " ) ) ,
UNO_QUERY ) ;
DBG_ASSERT ( xSaxWriter . is ( ) , " can't instantiate XML writer " ) ;
if ( ! xSaxWriter . is ( ) )
return sal_False ;
// connect XML writer to output stream
xSaxWriter - > setOutputStream ( xOutputStream ) ;
// prepare arguments (prepend doc handler to given arguments)
Reference < xml : : sax : : XDocumentHandler > xDocHandler ( xSaxWriter , UNO_QUERY ) ;
Sequence < Any > aArgs ( 2 ) ;
aArgs [ 0 ] < < = xDocHandler ;
aArgs [ 1 ] < < = rPropSet ;
// get filter component
Reference < document : : XExporter > xExporter (
rFactory - > createInstanceWithArguments (
OUString : : createFromAscii ( pComponentName ) , aArgs ) , UNO_QUERY ) ;
DBG_ASSERT ( xExporter . is ( ) ,
" can't instantiate export filter component " ) ;
if ( ! xExporter . is ( ) )
return sal_False ;
// connect model and filter
xExporter - > setSourceDocument ( xComponent ) ;
// filter!
Reference < XFilter > xFilter ( xExporter , UNO_QUERY ) ;
uno : : Sequence < PropertyValue > aProps ( 0 ) ;
xFilter - > filter ( aProps ) ;
uno : : Reference < lang : : XUnoTunnel > xFilterTunnel ;
xFilterTunnel = uno : : Reference < lang : : XUnoTunnel >
( xFilter , uno : : UNO_QUERY ) ;
SmXMLExport * pFilter = reinterpret_cast < SmXMLExport * > (
sal : : static_int_cast < sal_uIntPtr > (
xFilterTunnel - > getSomething ( SmXMLExport : : getUnoTunnelId ( ) ) ) ) ;
return pFilter ? pFilter - > GetSuccess ( ) : sal_True ;
}
/// export through an XML exporter component (storage version)
sal_Bool SmXMLExportWrapper : : WriteThroughComponent (
const Reference < embed : : XStorage > & xStorage ,
Reference < XComponent > xComponent ,
const sal_Char * pStreamName ,
Reference < lang : : XMultiServiceFactory > & rFactory ,
Reference < beans : : XPropertySet > & rPropSet ,
const sal_Char * pComponentName ,
sal_Bool bCompress
)
{
DBG_ASSERT ( xStorage . is ( ) , " Need storage! " ) ;
DBG_ASSERT ( NULL ! = pStreamName , " Need stream name! " ) ;
// open stream
Reference < io : : XStream > xStream ;
OUString sStreamName = OUString : : createFromAscii ( pStreamName ) ;
try
{
xStream = xStorage - > openStreamElement ( sStreamName ,
embed : : ElementModes : : READWRITE | embed : : ElementModes : : TRUNCATE ) ;
}
catch ( uno : : Exception & )
{
DBG_ERROR ( " Can't create output stream in package! " ) ;
return sal_False ;
}
String aPropName ( String : : CreateFromAscii ( RTL_CONSTASCII_STRINGPARAM ( " MediaType " ) ) ) ;
OUString aMime ( RTL_CONSTASCII_USTRINGPARAM ( " text/xml " ) ) ;
uno : : Any aAny ;
aAny < < = aMime ;
uno : : Reference < beans : : XPropertySet > xSet ( xStream , uno : : UNO_QUERY ) ;
xSet - > setPropertyValue ( aPropName , aAny ) ;
if ( ! bCompress )
{
aPropName = String : : CreateFromAscii ( RTL_CONSTASCII_STRINGPARAM ( " Compressed " ) ) ;
sal_Bool bFalse = sal_False ;
aAny . setValue ( & bFalse , : : getBooleanCppuType ( ) ) ;
xSet - > setPropertyValue ( aPropName , aAny ) ;
}
// even plain stream must be encrypted in encrypted document
OUString aTmpPropName ( RTL_CONSTASCII_USTRINGPARAM ( " UseCommonStoragePasswordEncryption " ) ) ;
sal_Bool bTrue = sal_True ;
aAny . setValue ( & bTrue , : : getBooleanCppuType ( ) ) ;
xSet - > setPropertyValue ( aTmpPropName , aAny ) ;
// set Base URL
if ( rPropSet . is ( ) )
{
OUString sPropName ( RTL_CONSTASCII_USTRINGPARAM ( " StreamName " ) ) ;
rPropSet - > setPropertyValue ( sPropName , makeAny ( sStreamName ) ) ;
}
// write the stuff
sal_Bool bRet = WriteThroughComponent ( xStream - > getOutputStream ( ) , xComponent , rFactory ,
rPropSet , pComponentName ) ;
// stream is closed by SAX parser
//if ( bRet )
// xStream->getOutputStream()->closeOutput();
return bRet ;
}
////////////////////////////////////////////////////////////
// #110680#
SmXMLExport : : SmXMLExport (
const : : com : : sun : : star : : uno : : Reference < : : com : : sun : : star : : lang : : XMultiServiceFactory > xServiceFactory ,
sal_uInt16 nExportFlags )
: SvXMLExport ( xServiceFactory , MAP_INCH , XML_MATH , nExportFlags ) ,
pTree ( 0 ) ,
bSuccess ( sal_False )
{
}
2009-10-06 07:38:24 +02:00
sal_Int64 SAL_CALL SmXMLExport : : getSomething (
const uno : : Sequence < sal_Int8 > & rId )
2009-05-19 09:31:27 +00:00
throw ( uno : : RuntimeException )
{
if ( rId . getLength ( ) = = 16 & &
0 = = rtl_compareMemory ( getUnoTunnelId ( ) . getConstArray ( ) ,
rId . getConstArray ( ) , 16 ) )
return sal : : static_int_cast < sal_Int64 > ( reinterpret_cast < sal_uIntPtr > ( this ) ) ;
return SvXMLExport : : getSomething ( rId ) ;
}
const uno : : Sequence < sal_Int8 > & SmXMLExport : : getUnoTunnelId ( ) throw ( )
{
static uno : : Sequence < sal_Int8 > * pSeq = 0 ;
if ( ! pSeq )
{
osl : : Guard < osl : : Mutex > aGuard ( osl : : Mutex : : getGlobalMutex ( ) ) ;
if ( ! pSeq )
{
static uno : : Sequence < sal_Int8 > aSeq ( 16 ) ;
rtl_createUuid ( ( sal_uInt8 * ) aSeq . getArray ( ) , 0 , sal_True ) ;
pSeq = & aSeq ;
}
}
return * pSeq ;
}
OUString SAL_CALL SmXMLExport_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExport_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExport_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
// EXPORT_OASIS is required here allthough there is no differrence between
// OOo and OASIS, because without the flag, a transformation to OOo would
// be chained in.
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_OASIS | EXPORT_ALL ) ;
}
////////////////////////////////////////////////////////////
OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLMetaExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_META ) ;
}
////////////////////////////////////////////////////////////
OUString SAL_CALL SmXMLExportMeta_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLOasisMetaExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExportMeta_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_OASIS | EXPORT_META ) ;
}
////////////////////////////////////////////////////////////
OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLSettingsExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_SETTINGS ) ;
}
////////////////////////////////////////////////////////////
OUString SAL_CALL SmXMLExportSettings_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLOasisSettingsExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExportSettings_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_OASIS | EXPORT_SETTINGS ) ;
}
////////////////////////////////////////////////////////////
OUString SAL_CALL SmXMLExportContent_getImplementationName ( ) throw ( )
{
return OUString ( RTL_CONSTASCII_USTRINGPARAM ( " com.sun.star.comp.Math.XMLContentExporter " ) ) ;
}
uno : : Sequence < OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames ( )
throw ( )
{
const OUString aServiceName ( EXPORT_SVC_NAME ) ;
const uno : : Sequence < OUString > aSeq ( & aServiceName , 1 ) ;
return aSeq ;
}
uno : : Reference < uno : : XInterface > SAL_CALL SmXMLExportContent_createInstance (
const uno : : Reference < lang : : XMultiServiceFactory > & rSMgr )
throw ( uno : : Exception )
{
// #110680#
// return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
// The EXPORT_OASIS flag is only required to avoid that a transformer is
// chanied in
return ( cppu : : OWeakObject * ) new SmXMLExport ( rSMgr , EXPORT_OASIS | EXPORT_CONTENT ) ;
}
////////////////////////////////////////////////////////////
// XServiceInfo
// override empty method from parent class
rtl : : OUString SAL_CALL SmXMLExport : : getImplementationName ( )
throw ( uno : : RuntimeException )
{
OUString aTxt ;
switch ( getExportFlags ( ) )
{
case EXPORT_META :
aTxt = SmXMLExportMeta_getImplementationName ( ) ;
break ;
case EXPORT_SETTINGS :
aTxt = SmXMLExportSettings_getImplementationName ( ) ;
break ;
case EXPORT_CONTENT :
aTxt = SmXMLExportContent_getImplementationName ( ) ;
break ;
case EXPORT_ALL :
default :
aTxt = SmXMLExport_getImplementationName ( ) ;
break ;
}
return aTxt ;
}
sal_uInt32 SmXMLExport : : exportDoc ( enum XMLTokenEnum eClass )
{
if ( ( getExportFlags ( ) & EXPORT_CONTENT ) = = 0 )
{
SvXMLExport : : exportDoc ( eClass ) ;
}
else
{
uno : : Reference < frame : : XModel > xModel = GetModel ( ) ;
uno : : Reference < lang : : XUnoTunnel > xTunnel ;
xTunnel = uno : : Reference < lang : : XUnoTunnel > ( xModel , uno : : UNO_QUERY ) ;
SmModel * pModel = reinterpret_cast < SmModel * >
( xTunnel - > getSomething ( SmModel : : getUnoTunnelId ( ) ) ) ;
if ( pModel )
{
SmDocShell * pDocShell =
static_cast < SmDocShell * > ( pModel - > GetObjectShell ( ) ) ;
pTree = pDocShell - > GetFormulaTree ( ) ;
aText = pDocShell - > GetText ( ) ;
}
GetDocHandler ( ) - > startDocument ( ) ;
/*Add xmlns line*/
SvXMLAttributeList & rList = GetAttrList ( ) ;
// make use of a default namespace
ResetNamespaceMap ( ) ; // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
_GetNamespaceMap ( ) . Add ( OUString : : createFromAscii ( " " ) , GetXMLToken ( XML_N_MATH ) , XML_NAMESPACE_MATH ) ;
rList . AddAttribute ( GetNamespaceMap ( ) . GetAttrNameByKey ( XML_NAMESPACE_MATH_IDX ) ,
GetNamespaceMap ( ) . GetNameByKey ( XML_NAMESPACE_MATH_IDX ) ) ;
//I think we need something like ImplExportEntities();
_ExportContent ( ) ;
GetDocHandler ( ) - > endDocument ( ) ;
}
bSuccess = sal_True ;
return 0 ;
}
void SmXMLExport : : _ExportContent ( )
{
SvXMLElementExport aEquation ( * this , XML_NAMESPACE_MATH , XML_MATH , sal_True , sal_True ) ;
SvXMLElementExport * pSemantics = 0 ;
if ( aText . Len ( ) )
{
pSemantics = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_SEMANTICS , sal_True , sal_True ) ;
}
ExportNodes ( pTree , 0 ) ;
if ( aText . Len ( ) )
{
// Convert symbol names
uno : : Reference < frame : : XModel > xModel = GetModel ( ) ;
uno : : Reference < lang : : XUnoTunnel > xTunnel ;
xTunnel = uno : : Reference < lang : : XUnoTunnel > ( xModel , uno : : UNO_QUERY ) ;
SmModel * pModel = reinterpret_cast < SmModel * >
( xTunnel - > getSomething ( SmModel : : getUnoTunnelId ( ) ) ) ;
SmDocShell * pDocShell = pModel ?
static_cast < SmDocShell * > ( pModel - > GetObjectShell ( ) ) : 0 ;
DBG_ASSERT ( pDocShell , " doc shell missing " ) ;
if ( pDocShell )
{
SmParser & rParser = pDocShell - > GetParser ( ) ;
BOOL bVal = rParser . IsExportSymbolNames ( ) ;
rParser . SetExportSymbolNames ( TRUE ) ;
SmNode * pTmpTree = rParser . Parse ( aText ) ;
aText = rParser . GetText ( ) ;
delete pTmpTree ;
rParser . SetExportSymbolNames ( bVal ) ;
}
AddAttribute ( XML_NAMESPACE_MATH , XML_ENCODING ,
OUString ( RTL_CONSTASCII_USTRINGPARAM ( " StarMath 5.0 " ) ) ) ;
SvXMLElementExport aAnnotation ( * this , XML_NAMESPACE_MATH ,
XML_ANNOTATION , sal_True , sal_False ) ;
GetDocHandler ( ) - > characters ( OUString ( aText ) ) ;
}
delete pSemantics ;
}
void SmXMLExport : : GetViewSettings ( Sequence < PropertyValue > & aProps )
{
uno : : Reference < frame : : XModel > xModel = GetModel ( ) ;
if ( ! xModel . is ( ) )
return ;
uno : : Reference < lang : : XUnoTunnel > xTunnel ;
xTunnel = uno : : Reference < lang : : XUnoTunnel > ( xModel , uno : : UNO_QUERY ) ;
SmModel * pModel = reinterpret_cast < SmModel * >
( xTunnel - > getSomething ( SmModel : : getUnoTunnelId ( ) ) ) ;
if ( ! pModel )
return ;
SmDocShell * pDocShell =
static_cast < SmDocShell * > ( pModel - > GetObjectShell ( ) ) ;
if ( ! pDocShell )
return ;
aProps . realloc ( 4 ) ;
PropertyValue * pValue = aProps . getArray ( ) ;
sal_Int32 nIndex = 0 ;
Rectangle aRect ( pDocShell - > GetVisArea ( ) ) ;
pValue [ nIndex ] . Name = OUString ( RTL_CONSTASCII_USTRINGPARAM ( " ViewAreaTop " ) ) ;
pValue [ nIndex + + ] . Value < < = aRect . Top ( ) ;
pValue [ nIndex ] . Name = OUString ( RTL_CONSTASCII_USTRINGPARAM ( " ViewAreaLeft " ) ) ;
pValue [ nIndex + + ] . Value < < = aRect . Left ( ) ;
pValue [ nIndex ] . Name = OUString ( RTL_CONSTASCII_USTRINGPARAM ( " ViewAreaWidth " ) ) ;
pValue [ nIndex + + ] . Value < < = aRect . GetWidth ( ) ;
pValue [ nIndex ] . Name = OUString ( RTL_CONSTASCII_USTRINGPARAM ( " ViewAreaHeight " ) ) ;
pValue [ nIndex + + ] . Value < < = aRect . GetHeight ( ) ;
}
void SmXMLExport : : GetConfigurationSettings ( Sequence < PropertyValue > & rProps )
{
Reference < XPropertySet > xProps ( GetModel ( ) , UNO_QUERY ) ;
if ( xProps . is ( ) )
{
Reference < XPropertySetInfo > xPropertySetInfo = xProps - > getPropertySetInfo ( ) ;
if ( xPropertySetInfo . is ( ) )
{
Sequence < Property > aProps = xPropertySetInfo - > getProperties ( ) ;
sal_Int32 nCount ( aProps . getLength ( ) ) ;
if ( nCount > 0 )
{
rProps . realloc ( nCount ) ;
PropertyValue * pProps = rProps . getArray ( ) ;
if ( pProps )
{
const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( " Formula " ) ) ;
const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( " BasicLibraries " ) ) ;
const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( " DialogLibraries " ) ) ;
const OUString sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( " RuntimeUID " ) ) ;
for ( sal_Int32 i = 0 ; i < nCount ; i + + , pProps + + )
{
const OUString & rPropName = aProps [ i ] . Name ;
if ( rPropName ! = sFormula & &
rPropName ! = sBasicLibraries & &
rPropName ! = sDialogLibraries & &
rPropName ! = sRuntimeUID )
{
pProps - > Name = rPropName ;
pProps - > Value = xProps - > getPropertyValue ( rPropName ) ;
}
}
}
}
}
}
}
void SmXMLExport : : ExportLine ( const SmNode * pNode , int nLevel )
{
ExportExpression ( pNode , nLevel ) ;
}
void SmXMLExport : : ExportBinaryHorizontal ( const SmNode * pNode , int nLevel )
{
ExportExpression ( pNode , nLevel ) ;
}
void SmXMLExport : : ExportUnaryHorizontal ( const SmNode * pNode , int nLevel )
{
ExportExpression ( pNode , nLevel ) ;
}
void SmXMLExport : : ExportExpression ( const SmNode * pNode , int nLevel )
{
SvXMLElementExport * pRow = 0 ;
ULONG nSize = pNode - > GetNumSubNodes ( ) ;
if ( nSize > 1 )
pRow = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MROW , sal_True , sal_True ) ;
//if (nSize)
//{
for ( USHORT i = 0 ; i < nSize ; i + + )
if ( const SmNode * pTemp = pNode - > GetSubNode ( i ) )
ExportNodes ( pTemp , nLevel + 1 ) ;
//}
#if 0
else
{
//This saves us from situations like "a newline" where the
//lack of a term following the newline would otherwise create
//a incorrect token like <mtr/>
SvXMLElementExport aDummy ( * this , XML_NAMESPACE_MATH , XML_MI , sal_True , sal_False ) ;
sal_Unicode nArse [ 2 ] = { ' \n ' , ' \0 ' } ;
GetDocHandler ( ) - > characters ( nArse ) ;
}
# endif
delete pRow ;
}
void SmXMLExport : : ExportBinaryVertical ( const SmNode * pNode , int nLevel )
{
DBG_ASSERT ( pNode - > GetNumSubNodes ( ) = = 3 , " Bad Fraction " ) ;
SvXMLElementExport aFraction ( * this , XML_NAMESPACE_MATH , XML_MFRAC , sal_True , sal_True ) ;
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel ) ;
ExportNodes ( pNode - > GetSubNode ( 2 ) , nLevel ) ;
}
void SmXMLExport : : ExportTable ( const SmNode * pNode , int nLevel )
{
SvXMLElementExport * pTable = 0 ;
USHORT nSize = pNode - > GetNumSubNodes ( ) ;
//If the list ends in newline then the last entry has
//no subnodes, the newline is superfulous so we just drop
//the last node, inclusion would create a bad MathML
//table
if ( nSize > = 1 & & pNode - > GetSubNode ( nSize - 1 ) - > GetNumSubNodes ( ) = = 0 )
- - nSize ;
2009-10-06 07:38:24 +02:00
// try to avoid creating a mtable element when the formula consists only
2009-05-19 09:31:27 +00:00
// of a single output line
if ( nLevel | | ( nSize > 1 ) )
pTable = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MTABLE , sal_True , sal_True ) ;
for ( USHORT i = 0 ; i < nSize ; i + + )
if ( const SmNode * pTemp = pNode - > GetSubNode ( i ) )
{
SvXMLElementExport * pRow = 0 ;
SvXMLElementExport * pCell = 0 ;
if ( pTable )
{
pRow = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MTR , sal_True , sal_True ) ;
pCell = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MTD , sal_True , sal_True ) ;
}
ExportNodes ( pTemp , nLevel + 1 ) ;
delete pCell ;
delete pRow ;
}
delete pTable ;
}
void SmXMLExport : : ExportMath ( const SmNode * pNode , int /*nLevel*/ )
{
const SmMathSymbolNode * pTemp = static_cast < const SmMathSymbolNode * > ( pNode ) ;
SvXMLElementExport aMath ( * this , XML_NAMESPACE_MATH , XML_MO , sal_True , sal_False ) ;
sal_Unicode nArse [ 2 ] ;
nArse [ 0 ] = pTemp - > GetText ( ) . GetChar ( 0 ) ;
sal_Unicode cTmp = ConvertMathToMathML ( nArse [ 0 ] ) ;
if ( cTmp ! = 0 )
nArse [ 0 ] = cTmp ;
DBG_ASSERT ( nArse [ 0 ] ! = 0xffff , " Non existant symbol " ) ;
nArse [ 1 ] = 0 ;
GetDocHandler ( ) - > characters ( nArse ) ;
}
void SmXMLExport : : ExportText ( const SmNode * pNode , int /*nLevel*/ )
{
SvXMLElementExport * pText ;
const SmTextNode * pTemp = static_cast < const SmTextNode * > ( pNode ) ;
switch ( pNode - > GetToken ( ) . eType )
{
default :
case TIDENT :
{
//Note that we change the fontstyle to italic for strings that
//are italic and longer than a single character.
sal_Bool bIsItalic = IsItalic ( pTemp - > GetFont ( ) ) ;
if ( ( pTemp - > GetText ( ) . Len ( ) > 1 ) & & bIsItalic )
AddAttribute ( XML_NAMESPACE_MATH , XML_MATHVARIANT , XML_ITALIC ) ;
else if ( ( pTemp - > GetText ( ) . Len ( ) = = 1 ) & & ! bIsItalic )
AddAttribute ( XML_NAMESPACE_MATH , XML_MATHVARIANT , XML_NORMAL ) ;
pText = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MI , sal_True , sal_False ) ;
break ;
}
case TNUMBER :
pText = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MN , sal_True , sal_False ) ;
break ;
case TTEXT :
pText = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MTEXT , sal_True , sal_False ) ;
break ;
}
GetDocHandler ( ) - > characters ( OUString ( pTemp - > GetText ( ) . GetBuffer ( ) ) ) ;
delete pText ;
}
void SmXMLExport : : ExportBlank ( const SmNode * /*pNode*/ , int /*nLevel*/ )
{
2009-10-06 07:38:24 +02:00
//!! exports an empty <mi> tag since for example "~_~" is allowed in
2009-05-19 09:31:27 +00:00
//!! Math (so it has no sense at all) but must not result in an empty
//!! <msub> tag in MathML !!
SvXMLElementExport * pText ;
//const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
pText = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MI , sal_True , sal_False ) ;
2009-10-06 07:38:24 +02:00
2009-05-19 09:31:27 +00:00
GetDocHandler ( ) - > characters ( OUString ( ) ) ;
delete pText ;
}
void SmXMLExport : : ExportSubSupScript ( const SmNode * pNode , int nLevel )
{
const SmNode * pSub = 0 ;
const SmNode * pSup = 0 ;
const SmNode * pCSub = 0 ;
const SmNode * pCSup = 0 ;
const SmNode * pLSub = 0 ;
const SmNode * pLSup = 0 ;
SvXMLElementExport * pThing = 0 , * pThing2 = 0 ;
//if we have prescripts at all then we must use the tensor notation
//This is one of those excellent locations where scope is vital to
//arrange the construction and destruction of the element helper
//classes correctly
pLSub = pNode - > GetSubNode ( LSUB + 1 ) ;
pLSup = pNode - > GetSubNode ( LSUP + 1 ) ;
if ( pLSub | | pLSup )
{
SvXMLElementExport aMultiScripts ( * this , XML_NAMESPACE_MATH ,
XML_MMULTISCRIPTS , sal_True , sal_True ) ;
if ( NULL ! = ( pCSub = pNode - > GetSubNode ( CSUB + 1 ) )
& & NULL ! = ( pCSup = pNode - > GetSubNode ( CSUP + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MUNDEROVER , sal_True , sal_True ) ;
}
else if ( NULL ! = ( pCSub = pNode - > GetSubNode ( CSUB + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MUNDER , sal_True , sal_True ) ;
}
else if ( NULL ! = ( pCSup = pNode - > GetSubNode ( CSUP + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MOVER , sal_True , sal_True ) ;
}
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ; //Main Term
if ( pCSub )
ExportNodes ( pCSub , nLevel + 1 ) ;
if ( pCSup )
ExportNodes ( pCSup , nLevel + 1 ) ;
delete pThing2 ;
pSub = pNode - > GetSubNode ( RSUB + 1 ) ;
pSup = pNode - > GetSubNode ( RSUP + 1 ) ;
if ( pSub | | pSup )
{
if ( pSub )
ExportNodes ( pSub , nLevel + 1 ) ;
else
{
SvXMLElementExport aNone ( * this , XML_NAMESPACE_MATH , XML_NONE , sal_True , sal_True ) ;
}
if ( pSup )
ExportNodes ( pSup , nLevel + 1 ) ;
else
{
SvXMLElementExport aNone ( * this , XML_NAMESPACE_MATH , XML_NONE , sal_True , sal_True ) ;
}
}
//Seperator element between suffix and prefix sub/sup pairs
{
SvXMLElementExport aPrescripts ( * this , XML_NAMESPACE_MATH ,
XML_MPRESCRIPTS , sal_True , sal_True ) ;
}
if ( pLSub )
ExportNodes ( pLSub , nLevel + 1 ) ;
else
{
SvXMLElementExport aNone ( * this , XML_NAMESPACE_MATH , XML_NONE ,
sal_True , sal_True ) ;
}
if ( pLSup )
ExportNodes ( pLSup , nLevel + 1 ) ;
else
{
SvXMLElementExport aNone ( * this , XML_NAMESPACE_MATH , XML_NONE ,
sal_True , sal_True ) ;
}
}
else
{
if ( NULL ! = ( pSub = pNode - > GetSubNode ( RSUB + 1 ) ) & &
NULL ! = ( pSup = pNode - > GetSubNode ( RSUP + 1 ) ) )
{
pThing = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MSUBSUP , sal_True , sal_True ) ;
}
else if ( NULL ! = ( pSub = pNode - > GetSubNode ( RSUB + 1 ) ) )
{
pThing = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MSUB ,
sal_True , sal_True ) ;
}
else if ( NULL ! = ( pSup = pNode - > GetSubNode ( RSUP + 1 ) ) )
{
pThing = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MSUP ,
sal_True , sal_True ) ;
}
if ( NULL ! = ( pCSub = pNode - > GetSubNode ( CSUB + 1 ) )
& & NULL ! = ( pCSup = pNode - > GetSubNode ( CSUP + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MUNDEROVER , sal_True , sal_True ) ;
}
else if ( NULL ! = ( pCSub = pNode - > GetSubNode ( CSUB + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MUNDER , sal_True , sal_True ) ;
}
else if ( NULL ! = ( pCSup = pNode - > GetSubNode ( CSUP + 1 ) ) )
{
pThing2 = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MOVER , sal_True , sal_True ) ;
}
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ; //Main Term
if ( pCSub )
ExportNodes ( pCSub , nLevel + 1 ) ;
if ( pCSup )
ExportNodes ( pCSup , nLevel + 1 ) ;
delete pThing2 ;
if ( pSub )
ExportNodes ( pSub , nLevel + 1 ) ;
if ( pSup )
ExportNodes ( pSup , nLevel + 1 ) ;
delete pThing ;
}
}
void SmXMLExport : : ExportBrace ( const SmNode * pNode , int nLevel )
{
const SmNode * pTemp ;
const SmNode * pLeft = pNode - > GetSubNode ( 0 ) ;
const SmNode * pRight = pNode - > GetSubNode ( 2 ) ;
SvXMLElementExport * pFences = 0 , * pRow = 0 ;
if ( ( ( pLeft ) & & ( pLeft - > GetToken ( ) . eType ! = TNONE ) ) & &
( ( pRight ) & & ( pRight - > GetToken ( ) . eType ! = TNONE ) ) & &
( pNode - > GetScaleMode ( ) = = SCALE_HEIGHT ) )
{
sal_Unicode nArse [ 2 ] ;
nArse [ 1 ] = 0 ;
nArse [ 0 ] = static_cast <
const SmMathSymbolNode * > ( pLeft ) - > GetText ( ) . GetChar ( 0 ) ;
DBG_ASSERT ( nArse [ 0 ] ! = 0xffff , " Non existant symbol " ) ;
AddAttribute ( XML_NAMESPACE_MATH , XML_OPEN , nArse ) ;
nArse [ 0 ] = static_cast <
const SmMathSymbolNode * > ( pRight ) - > GetText ( ) . GetChar ( 0 ) ;
DBG_ASSERT ( nArse [ 0 ] ! = 0xffff , " Non existant symbol " ) ;
AddAttribute ( XML_NAMESPACE_MATH , XML_CLOSE , nArse ) ;
pFences = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MFENCED ,
sal_True , sal_True ) ;
}
else if ( pLeft & & ( pLeft - > GetToken ( ) . eType ! = TNONE ) )
{
pRow = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MROW ,
sal_True , sal_True ) ;
if ( pNode - > GetScaleMode ( ) = = SCALE_HEIGHT )
AddAttribute ( XML_NAMESPACE_MATH , XML_STRETCHY , XML_TRUE ) ;
else
AddAttribute ( XML_NAMESPACE_MATH , XML_STRETCHY , XML_FALSE ) ;
ExportNodes ( pLeft , nLevel + 1 ) ;
}
else
pRow = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MROW ,
sal_True , sal_True ) ;
if ( NULL ! = ( pTemp = pNode - > GetSubNode ( 1 ) ) )
ExportNodes ( pTemp , nLevel + 1 ) ;
if ( pFences )
delete pFences ;
else if ( pRight & & ( pRight - > GetToken ( ) . eType ! = TNONE ) )
{
if ( pNode - > GetScaleMode ( ) = = SCALE_HEIGHT )
AddAttribute ( XML_NAMESPACE_MATH , XML_STRETCHY , XML_TRUE ) ;
else
AddAttribute ( XML_NAMESPACE_MATH , XML_STRETCHY , XML_FALSE ) ;
ExportNodes ( pRight , nLevel + 1 ) ;
}
delete pRow ;
}
void SmXMLExport : : ExportRoot ( const SmNode * pNode , int nLevel )
{
if ( pNode - > GetSubNode ( 0 ) )
{
SvXMLElementExport aRoot ( * this , XML_NAMESPACE_MATH , XML_MROOT , sal_True ,
sal_True ) ;
ExportNodes ( pNode - > GetSubNode ( 2 ) , nLevel + 1 ) ;
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ;
}
else
{
SvXMLElementExport aSqrt ( * this , XML_NAMESPACE_MATH , XML_MSQRT , sal_True ,
sal_True ) ;
ExportNodes ( pNode - > GetSubNode ( 2 ) , nLevel + 1 ) ;
}
}
void SmXMLExport : : ExportOperator ( const SmNode * pNode , int nLevel )
{
/*we need to either use content or font and size attributes
* here */
#if 0
{
SvXMLElementExport aMath ( * this , XML_NAMESPACE_MATH , XML_MO ,
sal_True , sal_False ) ;
SmTextNode * pTemp = ( SmTextNode * ) pNode - > GetSubNode ( 0 ) ;
GetDocHandler ( ) - > characters ( pTemp - > GetText ( ) ) ;
}
# endif
SvXMLElementExport aRow ( * this , XML_NAMESPACE_MATH , XML_MROW ,
sal_True , sal_True ) ;
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ;
ExportNodes ( pNode - > GetSubNode ( 1 ) , nLevel + 1 ) ;
}
void SmXMLExport : : ExportAttributes ( const SmNode * pNode , int nLevel )
{
SvXMLElementExport * pElement = 0 ;
if ( pNode - > GetToken ( ) . eType = = TUNDERLINE )
{
AddAttribute ( XML_NAMESPACE_MATH , XML_ACCENTUNDER ,
XML_TRUE ) ;
pElement = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MUNDER ,
sal_True , sal_True ) ;
}
else if ( pNode - > GetToken ( ) . eType ! = TOVERSTRIKE )
{
AddAttribute ( XML_NAMESPACE_MATH , XML_ACCENT ,
XML_TRUE ) ;
pElement = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH , XML_MOVER ,
sal_True , sal_True ) ;
}
ExportNodes ( pNode - > GetSubNode ( 1 ) , nLevel + 1 ) ;
switch ( pNode - > GetToken ( ) . eType )
{
case TOVERLINE :
{
//proper entity support required
SvXMLElementExport aMath ( * this , XML_NAMESPACE_MATH , XML_MO ,
sal_True , sal_True ) ;
#if 0
GetDocHandler ( ) - > characters (
OUString ( RTL_CONSTASCII_USTRINGPARAM ( " &overbar; " ) ) ) ;
# else
sal_Unicode nArse [ 2 ] = { 0xAF , 0x00 } ;
# endif
GetDocHandler ( ) - > characters ( nArse ) ;
}
break ;
case TUNDERLINE :
{
//proper entity support required
SvXMLElementExport aMath ( * this , XML_NAMESPACE_MATH , XML_MO ,
sal_True , sal_True ) ;
#if 0
GetDocHandler ( ) - > characters (
OUString ( RTL_CONSTASCII_USTRINGPARAM ( " &underbar; " ) ) ) ;
# else
sal_Unicode nArse [ 2 ] = { 0x0332 , 0x00 } ;
# endif
GetDocHandler ( ) - > characters ( nArse ) ;
}
break ;
case TOVERSTRIKE :
break ;
default :
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ;
break ;
}
delete pElement ;
}
static bool lcl_HasEffectOnMathvariant ( const SmTokenType eType )
{
2009-10-06 07:38:24 +02:00
return eType = = TBOLD | | eType = = TNBOLD | |
2009-05-19 09:31:27 +00:00
eType = = TITALIC | | eType = = TNBOLD | |
eType = = TSANS | | eType = = TSERIF | | eType = = TFIXED ;
2009-10-06 07:38:24 +02:00
}
2009-05-19 09:31:27 +00:00
void SmXMLExport : : ExportFont ( const SmNode * pNode , int nLevel )
{
SvXMLElementExport * pElement = 0 ;
//
// gather the mathvariant attribut relevant data from all
// successively following SmFontNodes...
//
int nBold = - 1 ; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
int nItalic = - 1 ; // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
int nSansSerifFixed = - 1 ;
SmTokenType eNodeType = TUNKNOWN ;
while ( lcl_HasEffectOnMathvariant ( ( eNodeType = pNode - > GetToken ( ) . eType ) ) )
{
switch ( eNodeType )
{
case TBOLD : nBold = 1 ; break ;
case TNBOLD : nBold = 0 ; break ;
case TITALIC : nItalic = 1 ; break ;
case TNITALIC : nItalic = 0 ; break ;
case TSANS : nSansSerifFixed = 0 ; break ;
case TSERIF : nSansSerifFixed = 1 ; break ;
case TFIXED : nSansSerifFixed = 2 ; break ;
default :
DBG_ASSERT ( 0 , " unexpected case " ) ;
}
// According to the parser every node that is to be evaluated heres
// has a single non-zero subnode at index 1!! Thus we only need to check
// that single node for follow-up nodes that have an effect on the attribute.
if ( pNode - > GetNumSubNodes ( ) > 1 & & pNode - > GetSubNode ( 1 ) & &
lcl_HasEffectOnMathvariant ( pNode - > GetSubNode ( 1 ) - > GetToken ( ) . eType ) )
{
pNode = pNode - > GetSubNode ( 1 ) ;
}
else
break ;
}
switch ( pNode - > GetToken ( ) . eType )
{
//wrap a phantom element around everything*/
case TPHANTOM :
pElement = new SvXMLElementExport ( * this , XML_NAMESPACE_MATH ,
XML_MPHANTOM , sal_True , sal_True ) ;
break ;
case TBLACK :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_BLACK ) ;
break ;
case TWHITE :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_WHITE ) ;
break ;
case TRED :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_RED ) ;
break ;
case TGREEN :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_GREEN ) ;
break ;
case TBLUE :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_BLUE ) ;
break ;
case TCYAN :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_AQUA ) ;
break ;
case TMAGENTA :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_FUCHSIA ) ;
break ;
case TYELLOW :
AddAttribute ( XML_NAMESPACE_MATH , XML_COLOR , XML_YELLOW ) ;
break ;
case TSIZE :
{
const SmFontNode * pFontNode = static_cast < const SmFontNode * > ( pNode ) ;
const Fraction & aFrac = pFontNode - > GetSizeParameter ( ) ;
OUStringBuffer sStrBuf ;
switch ( pFontNode - > GetSizeType ( ) )
{
case FNTSIZ_MULTIPLY :
SvXMLUnitConverter : : convertDouble ( sStrBuf ,
static_cast < double > ( aFrac * Fraction ( 100.00 ) ) ) ;
sStrBuf . append ( static_cast < sal_Unicode > ( ' % ' ) ) ;
break ;
case FNTSIZ_DIVIDE :
SvXMLUnitConverter : : convertDouble ( sStrBuf ,
static_cast < double > ( Fraction ( 100.00 ) / aFrac ) ) ;
sStrBuf . append ( static_cast < sal_Unicode > ( ' % ' ) ) ;
break ;
case FNTSIZ_ABSOLUT :
SvXMLUnitConverter : : convertDouble ( sStrBuf ,
static_cast < double > ( aFrac ) ) ;
sStrBuf . append (
GetXMLToken ( XML_UNIT_PT ) ) ;
break ;
default :
{
//The problem here is that the wheels fall off because
//font size is stored in 100th's of a mm not pts, and
//rounding errors take their toll on the original
//value specified in points.
//Must fix StarMath to retain the original pt values
Fraction aTemp = Sm100th_mmToPts ( pFontNode - > GetFont ( ) .
GetSize ( ) . Height ( ) ) ;
if ( pFontNode - > GetSizeType ( ) = = FNTSIZ_MINUS )
aTemp - = aFrac ;
else
aTemp + = aFrac ;
double mytest = static_cast < double > ( aTemp ) ;
mytest = : : rtl : : math : : round ( mytest , 1 ) ;
SvXMLUnitConverter : : convertDouble ( sStrBuf , mytest ) ;
sStrBuf . append ( GetXMLToken ( XML_UNIT_PT ) ) ;
}
break ;
}
OUString sStr ( sStrBuf . makeStringAndClear ( ) ) ;
AddAttribute ( XML_NAMESPACE_MATH , XML_MATHSIZE , sStr ) ;
}
break ;
case TBOLD :
case TITALIC :
case TNBOLD :
case TNITALIC :
case TFIXED :
case TSANS :
case TSERIF :
{
// nBold: -1 = yet undefined; 0 = false; 1 = true;
// nItalic: -1 = yet undefined; 0 = false; 1 = true;
// nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
const sal_Char * pText = " normal " ;
if ( nSansSerifFixed = = - 1 | | nSansSerifFixed = = 1 )
{
pText = " normal " ;
if ( nBold = = 1 & & nItalic ! = 1 )
pText = " bold " ;
else if ( nBold ! = 1 & & nItalic = = 1 )
pText = " italic " ;
else if ( nBold = = 1 & & nItalic = = 1 )
pText = " bold-italic " ;
}
else if ( nSansSerifFixed = = 0 )
{
pText = " sans-serif " ;
if ( nBold = = 1 & & nItalic ! = 1 )
pText = " bold-sans-serif " ;
else if ( nBold ! = 1 & & nItalic = = 1 )
pText = " sans-serif-italic " ;
else if ( nBold = = 1 & & nItalic = = 1 )
pText = " sans-serif-bold-italic " ;
}
else if ( nSansSerifFixed = = 2 )
pText = " monospace " ; // no modifiers allowed for monospace ...
else
{
DBG_ASSERT ( 0 , " unexpected case " ) ;
}
AddAttribute ( XML_NAMESPACE_MATH , XML_MATHVARIANT , A2OU ( pText ) ) ;
}
break ;
default :
break ;
}
#if 0
if ( pNode - > GetNumSubNodes ( ) > 1 ) //or in the future is a node that
//cannot take the currently supported
//properties
# endif
//for now we will just always export with a style and not worry about
//anyone else for the moment.
{
//wrap a style around it
SvXMLElementExport aStyle ( * this , XML_NAMESPACE_MATH , XML_MSTYLE , sal_True , sal_True ) ;
ExportExpression ( pNode , nLevel ) ;
}
#if 0
else
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel + 1 ) ;
# endif
delete pElement ;
}
void SmXMLExport : : ExportVerticalBrace ( const SmNode * pNode , int nLevel )
{
//Place the overbrace value OVER a vertical brace and then place that
//expression OVER the overbrace value, If someone can find a
//dedicated term in MathML to handle this overbrace/underbrace concept
//let me know. C.
XMLTokenEnum which ;
switch ( pNode - > GetToken ( ) . eType )
{
case TOVERBRACE :
default :
which = XML_MOVER ;
break ;
case TUNDERBRACE :
which = XML_MUNDER ;
break ;
}
DBG_ASSERT ( pNode - > GetNumSubNodes ( ) = = 3 , " Bad Vertical Brace " ) ;
SvXMLElementExport aOver1 ( * this , XML_NAMESPACE_MATH , which , sal_True , sal_True ) ;
{ //Scoping
// using accents will draw the over-/underbraces too close to the base
// see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
// also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
// AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT, XML_TRUE);
SvXMLElementExport aOver2 ( * this , XML_NAMESPACE_MATH , which , sal_True , sal_True ) ;
ExportNodes ( pNode - > GetSubNode ( 0 ) , nLevel ) ;
ExportNodes ( pNode - > GetSubNode ( 1 ) , nLevel ) ;
}
ExportNodes ( pNode - > GetSubNode ( 2 ) , nLevel ) ;
}
void SmXMLExport : : ExportMatrix ( const SmNode * pNode , int nLevel )
{
SvXMLElementExport aTable ( * this , XML_NAMESPACE_MATH , XML_MTABLE , sal_True , sal_True ) ;
const SmMatrixNode * pMatrix = static_cast < const SmMatrixNode * > ( pNode ) ;
USHORT i = 0 ;
for ( ULONG y = 0 ; y < pMatrix - > GetNumRows ( ) ; y + + )
{
SvXMLElementExport aRow ( * this , XML_NAMESPACE_MATH , XML_MTR , sal_True , sal_True ) ;
for ( ULONG x = 0 ; x < pMatrix - > GetNumCols ( ) ; x + + )
if ( const SmNode * pTemp = pNode - > GetSubNode ( i + + ) )
{
SvXMLElementExport aCell ( * this , XML_NAMESPACE_MATH , XML_MTD , sal_True , sal_True ) ;
ExportNodes ( pTemp , nLevel + 1 ) ;
}
}
}
void SmXMLExport : : ExportNodes ( const SmNode * pNode , int nLevel )
{
if ( ! pNode )
return ;
switch ( pNode - > GetType ( ) )
{
case NTABLE :
ExportTable ( pNode , nLevel ) ;
break ;
case NALIGN :
case NBRACEBODY :
case NEXPRESSION :
ExportExpression ( pNode , nLevel ) ;
break ;
case NLINE :
ExportLine ( pNode , nLevel ) ;
break ;
case NTEXT :
ExportText ( pNode , nLevel ) ;
break ;
case NSPECIAL : //NSPECIAL requires some sort of Entity preservation in the XML engine.
case NGLYPH_SPECIAL :
case NMATH :
{
sal_Unicode cTmp = 0 ;
const SmTextNode * pTemp = static_cast < const SmTextNode * > ( pNode ) ;
if ( pTemp - > GetText ( ) . Len ( ) > 0 )
cTmp = ConvertMathToMathML ( pTemp - > GetText ( ) . GetChar ( 0 ) ) ;
if ( cTmp = = 0 )
{
// no conversion to MathML implemented -> export it as text
// thus at least it will not vanish into nothing
ExportText ( pNode , nLevel ) ;
}
2009-10-06 07:38:24 +02:00
else
2009-05-19 09:31:27 +00:00
{
//To fully handle generic MathML we need to implement the full
//operator dictionary, we will generate MathML with explicit
//stretchiness for now.
sal_Int16 nLength = GetAttrList ( ) . getLength ( ) ;
sal_Bool bAddStretch = sal_True ;
for ( sal_Int16 i = 0 ; i < nLength ; i + + )
{
OUString sLocalName ;
sal_uInt16 nPrefix = GetNamespaceMap ( ) . GetKeyByAttrName (
GetAttrList ( ) . getNameByIndex ( i ) , & sLocalName ) ;
if ( ( XML_NAMESPACE_MATH = = nPrefix ) & &
IsXMLToken ( sLocalName , XML_STRETCHY ) )
{
bAddStretch = sal_False ;
break ;
}
}
if ( bAddStretch )
{
AddAttribute ( XML_NAMESPACE_MATH , XML_STRETCHY , XML_FALSE ) ;
}
ExportMath ( pNode , nLevel ) ;
}
}
break ;
case NPLACE :
ExportMath ( pNode , nLevel ) ;
break ;
case NBINHOR :
ExportBinaryHorizontal ( pNode , nLevel ) ;
break ;
case NUNHOR :
ExportUnaryHorizontal ( pNode , nLevel ) ;
break ;
case NBRACE :
ExportBrace ( pNode , nLevel ) ;
break ;
case NBINVER :
ExportBinaryVertical ( pNode , nLevel ) ;
break ;
case NSUBSUP :
ExportSubSupScript ( pNode , nLevel ) ;
break ;
case NROOT :
ExportRoot ( pNode , nLevel ) ;
break ;
case NOPER :
ExportOperator ( pNode , nLevel ) ;
break ;
case NATTRIBUT :
ExportAttributes ( pNode , nLevel ) ;
break ;
case NFONT :
ExportFont ( pNode , nLevel ) ;
break ;
case NVERTICAL_BRACE :
ExportVerticalBrace ( pNode , nLevel ) ;
break ;
case NMATRIX :
ExportMatrix ( pNode , nLevel ) ;
break ;
case NBLANK :
ExportBlank ( pNode , nLevel ) ;
break ;
default :
DBG_ASSERT ( 0 , " Warning: failed to export a node? " ) ;
break ;
#if 0
default :
{
ULONG nSize = pNode - > GetNumSubNodes ( ) ;
for ( ULONG i = 0 ; i < nSize ; i + + )
if ( SmNode * pTemp = pNode - > GetSubNode ( i ) )
ExportNodes ( pTemp , nLevel + 1 ) ;
}
break ;
# endif
}
}
////////////////////////////////////////////////////////////