/Users/ericb/Desktop/SRC680_m247/starmath/source/mathml.cxx

Go to the documentation of this file.
00001 /*************************************************************************
00002  *
00003  *  OpenOffice.org - a multi-platform office productivity suite
00004  *
00005  *  $RCSfile: mathml.cxx,v $
00006  *
00007  *  $Revision: 1.84 $
00008  *
00009  *  last change: $Author: hr $ $Date: 2007/06/26 10:01:03 $
00010  *
00011  *  The Contents of this file are made available subject to
00012  *  the terms of GNU Lesser General Public License Version 2.1.
00013  *
00014  *
00015  *    GNU Lesser General Public License Version 2.1
00016  *    =============================================
00017  *    Copyright 2005 by Sun Microsystems, Inc.
00018  *    901 San Antonio Road, Palo Alto, CA 94303, USA
00019  *
00020  *    This library is free software; you can redistribute it and/or
00021  *    modify it under the terms of the GNU Lesser General Public
00022  *    License version 2.1, as published by the Free Software Foundation.
00023  *
00024  *    This library is distributed in the hope that it will be useful,
00025  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00026  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027  *    Lesser General Public License for more details.
00028  *
00029  *    You should have received a copy of the GNU Lesser General Public
00030  *    License along with this library; if not, write to the Free Software
00031  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00032  *    MA  02111-1307  USA
00033  *
00034  ************************************************************************/
00035 
00036 // MARKER(update_precomp.py): autogen include statement, do not remove
00037 #include "precompiled_starmath.hxx"
00038 
00039 /*
00040  Warning: The SvXMLElementExport helper class creates the beginning and
00041  closing tags of xml elements in its constructor and destructor, so theres
00042  hidden stuff going on, on occasion the ordering of these classes declarations
00043  may be significant
00044 */
00045 
00046 /*todo: Change characters and tcharacters to accumulate the characters together
00047 into one string, xml parser hands them to us line by line rather than all in
00048 one go*/
00049 
00050 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
00051 #include <com/sun/star/container/XNameAccess.hpp>
00052 #endif
00053 #ifndef _COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
00054 #include <com/sun/star/embed/ElementModes.hpp>
00055 #endif
00056 
00057 #ifndef _TOOLS_DEBUG_H
00058 #include <tools/debug.hxx>
00059 #endif
00060 #ifndef _URLOBJ_HXX
00061 #include <tools/urlobj.hxx>
00062 #endif
00063 #ifndef INCLUDED_RTL_MATH_HXX
00064 #include <rtl/math.hxx>
00065 #endif
00066 #ifndef _SFXECODE_HXX
00067 #include <svtools/sfxecode.hxx>
00068 #endif
00069 #ifndef INCLUDED_SVTOOLS_SAVEOPT_HXX
00070 #include <svtools/saveopt.hxx>
00071 #endif
00072 #ifndef _SFXDOCFILE_HXX
00073 #include <sfx2/docfile.hxx>
00074 #endif
00075 #ifndef _SFXSTRITEM_HXX
00076 #include <svtools/stritem.hxx>
00077 #endif
00078 
00079 #ifndef UNOMODEL_HXX
00080 #include <unomodel.hxx>
00081 #endif
00082 #ifndef MATHML_HXX
00083 #include <mathml.hxx>
00084 #endif
00085 #ifndef DOCUMENT_HXX
00086 #include <document.hxx>
00087 #endif
00088 #ifndef UTILITY_HXX
00089 #include <utility.hxx>
00090 #endif
00091 
00092 #ifndef _OSL_MUTEX_HXX_
00093 #include <osl/mutex.hxx>
00094 #endif
00095 
00096 #ifndef _COM_SUN_STAR_UNO_ANY_H_
00097 #include <com/sun/star/uno/Any.h>
00098 #endif
00099 
00100 #ifndef _XMLOFF_XMLNMSPE_HXX
00101 #include <xmloff/xmlnmspe.hxx>
00102 #endif
00103 #ifndef _XMLOFF_XMLTOKEN_HXX
00104 #include <xmloff/xmltoken.hxx>
00105 #endif
00106 #ifndef _XMLOFF_NMSPMAP_HXX
00107 #include <xmloff/nmspmap.hxx>
00108 #endif
00109 #ifndef _XMLOFF_ATTRLIST_HXX
00110 #include <xmloff/attrlist.hxx>
00111 #endif
00112 #ifndef _XMLOFF_XMLUCONV_HXX
00113 #include <xmloff/xmluconv.hxx>
00114 #endif
00115 #ifndef _XMLOFF_XMLMETAI_HXX
00116 #include <xmloff/xmlmetai.hxx>
00117 #endif
00118 
00119 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX_
00120 #include <unotools/processfactory.hxx>
00121 #endif
00122 #ifndef _UTL_STREAM_WRAPPER_HXX_
00123 #include <unotools/streamwrap.hxx>
00124 #endif
00125 
00126 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
00127 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
00128 #include <com/sun/star/xml/sax/InputSource.hpp>
00129 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
00130 #include <com/sun/star/xml/sax/XParser.hpp>
00131 #include <com/sun/star/io/XActiveDataSource.hpp>
00132 #include <com/sun/star/io/XActiveDataControl.hpp>
00133 
00134 #ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_
00135 #include <com/sun/star/packages/zip/ZipIOException.hpp>
00136 #endif
00137 #ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATORFACTORY_HPP_
00138 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
00139 #endif
00140 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
00141 #include <com/sun/star/beans/PropertyAttribute.hpp>
00142 #endif
00143 #ifndef _COMPHELPER_GENERICPROPERTYSET_HXX_
00144 #include <comphelper/genericpropertyset.hxx>
00145 #endif
00146 
00147 #ifndef _SFX_ITEMPROP_HXX
00148 #include <svtools/itemprop.hxx>
00149 #endif
00150 
00151 #include <sfx2/frame.hxx>
00152 
00153 using namespace com::sun::star::uno;
00154 using namespace com::sun::star::lang;
00155 using namespace com::sun::star::document;
00156 using namespace com::sun::star::container;
00157 using namespace com::sun::star::beans;
00158 using namespace com::sun::star;
00159 using namespace ::xmloff::token;
00160 using ::rtl::OUString;
00161 using ::rtl::OUStringBuffer;
00162 
00163 #ifndef MATHTYPE_HXX
00164 #include "mathtype.hxx"
00165 #endif
00166 
00167 #ifndef STARMATH_HRC
00168 #include <starmath.hrc>
00169 #endif
00170 #ifndef PARSE_HXX
00171 #include <parser.hxx>
00172 #endif
00173 
00174 #define IMPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLImportFilter")
00175 #define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
00176 
00177 #undef WANTEXCEPT
00178 
00180 ULONG SmXMLWrapper::ReadThroughComponent(
00181     Reference<io::XInputStream> xInputStream,
00182     Reference<XComponent> xModelComponent,
00183     Reference<lang::XMultiServiceFactory> & rFactory,
00184     Reference<beans::XPropertySet> & rPropSet,
00185     const sal_Char* pFilterName,
00186     sal_Bool bEncrypted )
00187 {
00188     ULONG nError = ERRCODE_SFX_DOLOADFAILED;
00189     DBG_ASSERT(xInputStream.is(), "input stream missing");
00190     DBG_ASSERT(xModelComponent.is(), "document missing");
00191     DBG_ASSERT(rFactory.is(), "factory missing");
00192     DBG_ASSERT(NULL != pFilterName,"I need a service name for the component!");
00193 
00194     // prepare ParserInputSrouce
00195     xml::sax::InputSource aParserInput;
00196     aParserInput.aInputStream = xInputStream;
00197 
00198     // get parser
00199     Reference< xml::sax::XParser > xParser(
00200         rFactory->createInstance(
00201             OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
00202         UNO_QUERY );
00203     DBG_ASSERT( xParser.is(), "Can't create parser" );
00204     if( !xParser.is() )
00205         return nError;
00206 
00207     Sequence<Any> aArgs( 1 );
00208     aArgs[0] <<= rPropSet;
00209 
00210     // get filter
00211     Reference< xml::sax::XDocumentHandler > xFilter(
00212         rFactory->createInstanceWithArguments(
00213             OUString::createFromAscii(pFilterName), aArgs ),
00214         UNO_QUERY );
00215     DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." );
00216     if( !xFilter.is() )
00217         return nError;
00218 
00219     // connect parser and filter
00220     xParser->setDocumentHandler( xFilter );
00221 
00222     // connect model and filter
00223     Reference < XImporter > xImporter( xFilter, UNO_QUERY );
00224     xImporter->setTargetDocument( xModelComponent );
00225 
00226     // finally, parser the stream
00227     try
00228     {
00229         xParser->parseStream( aParserInput );
00230 
00231         uno::Reference<lang::XUnoTunnel> xFilterTunnel;
00232         xFilterTunnel = uno::Reference<lang::XUnoTunnel>
00233             ( xFilter, uno::UNO_QUERY );
00234         SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
00235                 sal::static_int_cast< sal_uIntPtr >(
00236                 xFilterTunnel->getSomething( SmXMLImport::getUnoTunnelId() )));
00237         if( pFilter && pFilter->GetSuccess() )
00238             nError = 0;
00239     }
00240     catch( xml::sax::SAXParseException& )
00241     {
00242         if( bEncrypted )
00243             nError = ERRCODE_SFX_WRONGPASSWORD;
00244     }
00245     catch( xml::sax::SAXException& )
00246     {
00247         if( bEncrypted )
00248             nError = ERRCODE_SFX_WRONGPASSWORD;
00249     }
00250     catch( packages::zip::ZipIOException& )
00251     {
00252         nError = ERRCODE_IO_BROKENPACKAGE;
00253     }
00254     catch( io::IOException& )
00255     {
00256     }
00257 
00258     return nError;
00259 }
00260 
00261 ULONG SmXMLWrapper::ReadThroughComponent(
00262     const uno::Reference< embed::XStorage >& xStorage,
00263     Reference<XComponent> xModelComponent,
00264     const sal_Char* pStreamName,
00265     const sal_Char* pCompatibilityStreamName,
00266     Reference<lang::XMultiServiceFactory> & rFactory,
00267     Reference<beans::XPropertySet> & rPropSet,
00268     const sal_Char* pFilterName )
00269 {
00270     DBG_ASSERT(xStorage.is(), "Need storage!");
00271     DBG_ASSERT(NULL != pStreamName, "Please, please, give me a name!");
00272 
00273     // open stream (and set parser input)
00274     OUString sStreamName = OUString::createFromAscii(pStreamName);
00275     uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
00276     if ( !xAccess->hasByName(sStreamName) || !xStorage->isStreamElement(sStreamName) )
00277     {
00278         // stream name not found! Then try the compatibility name.
00279         // do we even have an alternative name?
00280         if ( pCompatibilityStreamName )
00281             sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
00282     }
00283 
00284     // get input stream
00285     try
00286     {
00287         uno::Reference < io::XStream > xEventsStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
00288 
00289         // determine if stream is encrypted or not
00290         uno::Reference < beans::XPropertySet > xProps( xEventsStream, uno::UNO_QUERY );
00291         Any aAny = xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
00292         sal_Bool bEncrypted = sal_False;
00293         if ( aAny.getValueType() == ::getBooleanCppuType() )
00294             aAny >>= bEncrypted;
00295 
00296                 // set Base URL
00297                 if( rPropSet.is() )
00298                 {
00299                         OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
00300                         rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
00301                 }
00302 
00303 
00304         Reference < io::XInputStream > xStream = xEventsStream->getInputStream();
00305         return ReadThroughComponent( xStream, xModelComponent, rFactory, rPropSet, pFilterName, bEncrypted );
00306     }
00307         catch ( packages::WrongPasswordException& )
00308         {
00309                 return ERRCODE_SFX_WRONGPASSWORD;
00310         }
00311     catch( packages::zip::ZipIOException& )
00312     {
00313         return ERRCODE_IO_BROKENPACKAGE;
00314     }
00315     catch ( uno::Exception& )
00316     {
00317     }
00318 
00319     return ERRCODE_SFX_DOLOADFAILED;
00320 }
00321 
00322 ULONG SmXMLWrapper::Import(SfxMedium &rMedium)
00323 {
00324     ULONG nError = ERRCODE_SFX_DOLOADFAILED;
00325 
00326     uno::Reference<lang::XMultiServiceFactory> xServiceFactory(
00327         utl::getProcessServiceFactory());
00328     DBG_ASSERT(xServiceFactory.is(), "XMLReader::Read: got no service manager");
00329     if( !xServiceFactory.is() )
00330         return nError;
00331 
00332     //Make a model component from our SmModel
00333     uno::Reference< lang::XComponent > xModelComp( xModel, uno::UNO_QUERY );
00334     DBG_ASSERT( xModelComp.is(), "XMLReader::Read: got no model" );
00335 
00336     // try to get an XStatusIndicator from the Medium
00337     uno::Reference<task::XStatusIndicator> xStatusIndicator;
00338 
00339     sal_Bool bEmbedded = sal_False;
00340     uno::Reference <lang::XUnoTunnel> xTunnel;
00341     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
00342     SmModel *pModel = reinterpret_cast<SmModel *>
00343         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
00344 
00345     SmDocShell *pDocShell = pModel ?
00346             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
00347     if (pDocShell)
00348     {
00349 //        if (pDocShell->GetMedium())
00350         {
00351             DBG_ASSERT( pDocShell->GetMedium() == &rMedium,
00352                     "different SfxMedium found" );
00353 
00354             SfxItemSet* pSet = rMedium.GetItemSet();
00355             if (pSet)
00356             {
00357                 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
00358                     pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
00359                 if (pItem)
00360                     pItem->GetValue() >>= xStatusIndicator;
00361             }
00362         }
00363 
00364         if( SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
00365             bEmbedded = sal_True;
00366     }
00367 
00368         comphelper::PropertyMapEntry aInfoMap[] =
00369         {
00370                 { "PrivateData", sizeof("PrivateData")-1, 0,
00371                           &::getCppuType( (Reference<XInterface> *)0 ),
00372                           beans::PropertyAttribute::MAYBEVOID, 0 },
00373                 { "BaseURI", sizeof("BaseURI")-1, 0,
00374                           &::getCppuType( (OUString *)0 ),
00375                           beans::PropertyAttribute::MAYBEVOID, 0 },
00376                 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
00377                           &::getCppuType( (OUString *)0 ),
00378                           beans::PropertyAttribute::MAYBEVOID, 0 },
00379                 { "StreamName", sizeof("StreamName")-1, 0,
00380                           &::getCppuType( (OUString *)0 ),
00381                           beans::PropertyAttribute::MAYBEVOID, 0 },
00382                 { NULL, 0, 0, NULL, 0, 0 }
00383         };
00384         uno::Reference< beans::XPropertySet > xInfoSet(
00385                                 comphelper::GenericPropertySet_CreateInstance(
00386                                                         new comphelper::PropertySetInfo( aInfoMap ) ) );
00387 
00388         // Set base URI
00389         OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
00390     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL() ) );
00391 
00392     sal_Int32 nSteps=3;
00393     if( !(rMedium.IsStorage()))
00394         nSteps = 1;
00395 
00396     sal_Int32 nProgressRange(nSteps);
00397     if (xStatusIndicator.is())
00398     {
00399         xStatusIndicator->start(String(SmResId(STR_STATSTR_READING)),
00400             nProgressRange);
00401     }
00402 
00403     nSteps=0;
00404     if (xStatusIndicator.is())
00405         xStatusIndicator->setValue(nSteps++);
00406 
00407     if( rMedium.IsStorage())
00408     {
00409                 // TODO/LATER: handle the case of embedded links gracefully
00410                 if( bEmbedded ) // && !rMedium.GetStorage()->IsRoot() )
00411                 {
00412                         OUString aName( RTL_CONSTASCII_USTRINGPARAM( "dummyObjName" ) );
00413                         if ( rMedium.GetItemSet() )
00414                         {
00415                                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
00416                         rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
00417                                 if ( pDocHierarchItem )
00418                                         aName = pDocHierarchItem->GetValue();
00419                         }
00420 
00421                         if( aName.getLength() )
00422                         {
00423                                 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
00424                                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
00425                         }
00426                 }
00427 
00428                 sal_Bool bOASIS = ( SotStorage::GetVersion( rMedium.GetStorage() ) > SOFFICE_FILEFORMAT_60 );
00429         if (xStatusIndicator.is())
00430             xStatusIndicator->setValue(nSteps++);
00431 
00432         ULONG nWarn = ReadThroughComponent(
00433             rMedium.GetStorage(), xModelComp, "meta.xml", "Meta.xml",
00434             xServiceFactory, xInfoSet,
00435                                 (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaImporter"
00436                                                 : "com.sun.star.comp.Math.XMLMetaImporter")     );
00437 
00438                 if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
00439                 {
00440                 if (xStatusIndicator.is())
00441                 xStatusIndicator->setValue(nSteps++);
00442 
00443                 nWarn = ReadThroughComponent(
00444                 rMedium.GetStorage(), xModelComp, "settings.xml", 0,
00445                 xServiceFactory, xInfoSet,
00446                                 (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsImporter"
00447                                                 : "com.sun.star.comp.Math.XMLSettingsImporter" ) );
00448 
00449                         if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
00450                         {
00451                         if (xStatusIndicator.is())
00452                         xStatusIndicator->setValue(nSteps++);
00453 
00454                         nError = ReadThroughComponent(
00455                                 rMedium.GetStorage(), xModelComp, "content.xml", "Content.xml",
00456                                 xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter" );
00457                         }
00458                         else
00459                                 nError = ERRCODE_IO_BROKENPACKAGE;
00460                 }
00461                 else
00462                         nError = ERRCODE_IO_BROKENPACKAGE;
00463     }
00464     else
00465     {
00466         Reference<io::XInputStream> xInputStream =
00467             new utl::OInputStreamWrapper(rMedium.GetInStream());
00468 
00469         if (xStatusIndicator.is())
00470             xStatusIndicator->setValue(nSteps++);
00471 
00472         nError = ReadThroughComponent( xInputStream, xModelComp,
00473             xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter", FALSE );
00474     }
00475 
00476     if (xStatusIndicator.is())
00477         xStatusIndicator->end();
00478     return nError;
00479 }
00480 
00481 SmXMLImport::SmXMLImport(
00482         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
00483         sal_uInt16 nImportFlags)
00484 :       SvXMLImport( xServiceFactory, nImportFlags ),
00485     pPresLayoutElemTokenMap(0),
00486     pPresLayoutAttrTokenMap(0),
00487     pFencedAttrTokenMap(0),
00488     pOperatorAttrTokenMap(0),
00489     pAnnotationAttrTokenMap(0),
00490     pPresElemTokenMap(0),
00491     pPresScriptEmptyElemTokenMap(0),
00492     pPresTableElemTokenMap(0),
00493     pColorTokenMap(0),
00494     bSuccess(sal_False)
00495 {
00496 }
00497 
00498 SmXMLImport::SmXMLImport(
00499         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
00500         com::sun::star::uno::Reference<com::sun::star::frame::XModel> &rModel,
00501     const rtl::OUString & /*rFileName*/ )
00502 :       SvXMLImport( xServiceFactory, rModel ) ,
00503     pPresLayoutElemTokenMap(0),
00504     pPresLayoutAttrTokenMap(0),
00505     pFencedAttrTokenMap(0),
00506     pOperatorAttrTokenMap(0),
00507     pAnnotationAttrTokenMap(0),
00508     pPresElemTokenMap(0),
00509     pPresScriptEmptyElemTokenMap(0),
00510     pPresTableElemTokenMap(0),
00511     pColorTokenMap(0),
00512     bSuccess(sal_False)
00513 {
00514 }
00515 
00516 const uno::Sequence< sal_Int8 > & SmXMLImport::getUnoTunnelId() throw()
00517 {
00518     static uno::Sequence< sal_Int8 > * pSeq = 0;
00519     if( !pSeq )
00520     {
00521         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
00522         if( !pSeq )
00523         {
00524             static uno::Sequence< sal_Int8 > aSeq( 16 );
00525             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
00526             pSeq = &aSeq;
00527         }
00528     }
00529     return *pSeq;
00530 }
00531 
00532 // #110680#
00533 SmXMLExport::SmXMLExport(
00534         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
00535         sal_uInt16 nExportFlags)
00536 :       SvXMLExport( xServiceFactory, MAP_INCH, XML_MATH, nExportFlags ) ,
00537         pTree(0) ,
00538     bSuccess(sal_False)
00539 {
00540 }
00541 
00542 // #110680#
00543 SmXMLExport::SmXMLExport(
00544         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
00545         const SmNode *pIn,
00546         const rtl::OUString &rFileName,
00547         com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler> &rHandler)
00548 :       SvXMLExport( xServiceFactory, rFileName, rHandler ),
00549         pTree(pIn),
00550         bSuccess(sal_False)
00551 {
00552 }
00553 
00554 const uno::Sequence< sal_Int8 > & SmXMLExport::getUnoTunnelId() throw()
00555 {
00556     static uno::Sequence< sal_Int8 > * pSeq = 0;
00557     if( !pSeq )
00558     {
00559         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
00560         if( !pSeq )
00561         {
00562             static uno::Sequence< sal_Int8 > aSeq( 16 );
00563             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
00564             pSeq = &aSeq;
00565         }
00566     }
00567     return *pSeq;
00568 }
00569 
00570 //------------------------------------------------------------------------------
00571 
00572 OUString SAL_CALL SmXMLImport_getImplementationName() throw()
00573 {
00574     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLImporter" ) );
00575 }
00576 
00577 uno::Sequence< OUString > SAL_CALL SmXMLImport_getSupportedServiceNames()
00578         throw()
00579 {
00580     const OUString aServiceName( IMPORT_SVC_NAME );
00581     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00582         return aSeq;
00583 }
00584 
00585 uno::Reference< uno::XInterface > SAL_CALL SmXMLImport_createInstance(
00586     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00587     throw( uno::Exception )
00588 {
00589         // #110680#
00590     // return (cppu::OWeakObject*)new SmXMLImport(IMPORT_ALL);
00591     return (cppu::OWeakObject*)new SmXMLImport(rSMgr, IMPORT_ALL);
00592 }
00593 
00594 //------------------------------------------------------------------------------
00595 
00596 OUString SAL_CALL SmXMLExport_getImplementationName() throw()
00597 {
00598     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
00599 }
00600 
00601 uno::Sequence< OUString > SAL_CALL SmXMLExport_getSupportedServiceNames()
00602         throw()
00603 {
00604     const OUString aServiceName( EXPORT_SVC_NAME );
00605     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00606         return aSeq;
00607 }
00608 
00609 uno::Reference< uno::XInterface > SAL_CALL SmXMLExport_createInstance(
00610     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00611     throw( uno::Exception )
00612 {
00613         // #110680#
00614     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
00615         // EXPORT_OASIS is required here allthough there is no differrence between
00616         // OOo and OASIS, because without the flag, a transformation to OOo would
00617         // be chained in.
00618     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_ALL );
00619 }
00620 
00621 //------------------------------------------------------------------------------
00622 
00623 OUString SAL_CALL SmXMLImportMeta_getImplementationName() throw()
00624 {
00625     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaImporter" ) );
00626 }
00627 
00628 uno::Sequence< OUString > SAL_CALL SmXMLImportMeta_getSupportedServiceNames()
00629         throw()
00630 {
00631     const OUString aServiceName( IMPORT_SVC_NAME );
00632     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00633         return aSeq;
00634 }
00635 
00636 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportMeta_createInstance(
00637     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00638     throw( uno::Exception )
00639 {
00640         // #110680#
00641     // return (cppu::OWeakObject*)new SmXMLImport( IMPORT_META );
00642     return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_META );
00643 }
00644 
00645 //------------------------------------------------------------------------------
00646 
00647 OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName() throw()
00648 {
00649 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
00650 }
00651 
00652 uno::Sequence< OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames()
00653         throw()
00654 {
00655 const OUString aServiceName( EXPORT_SVC_NAME );
00656 const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00657         return aSeq;
00658 }
00659 
00660 uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance(
00661 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00662 throw( uno::Exception )
00663 {
00664 // #110680#
00665 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
00666 return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_META );
00667 }
00668 
00669 //------------------------------------------------------------------------------
00670 
00671 OUString SAL_CALL SmXMLExportMeta_getImplementationName() throw()
00672 {
00673 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
00674 }
00675 
00676 uno::Sequence< OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames()
00677         throw()
00678 {
00679 const OUString aServiceName( EXPORT_SVC_NAME );
00680 const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00681         return aSeq;
00682 }
00683 
00684 uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMeta_createInstance(
00685 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00686 throw( uno::Exception )
00687 {
00688 // #110680#
00689 // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
00690 return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_META );
00691 }
00692 
00693 //------------------------------------------------------------------------------
00694 
00695 OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw()
00696 {
00697     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsImporter" ) );
00698 }
00699 
00700 uno::Sequence< OUString > SAL_CALL SmXMLImportSettings_getSupportedServiceNames()
00701         throw()
00702 {
00703     const OUString aServiceName( IMPORT_SVC_NAME );
00704     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00705         return aSeq;
00706 }
00707 
00708 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportSettings_createInstance(
00709     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00710     throw( uno::Exception )
00711 {
00712         // #110680#
00713     // return (cppu::OWeakObject*)new SmXMLImport( IMPORT_SETTINGS );
00714     return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_SETTINGS );
00715 }
00716 
00717 //------------------------------------------------------------------------------
00718 
00719 OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName() throw()
00720 {
00721     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
00722 }
00723 
00724 uno::Sequence< OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames()
00725         throw()
00726 {
00727     const OUString aServiceName( EXPORT_SVC_NAME );
00728     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00729         return aSeq;
00730 }
00731 
00732 uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance(
00733     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00734     throw( uno::Exception )
00735 {
00736         // #110680#
00737     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
00738     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_SETTINGS );
00739 }
00740 
00741 //------------------------------------------------------------------------------
00742 
00743 OUString SAL_CALL SmXMLExportSettings_getImplementationName() throw()
00744 {
00745     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
00746 }
00747 
00748 uno::Sequence< OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames()
00749         throw()
00750 {
00751     const OUString aServiceName( EXPORT_SVC_NAME );
00752     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00753         return aSeq;
00754 }
00755 
00756 uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettings_createInstance(
00757     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00758     throw( uno::Exception )
00759 {
00760         // #110680#
00761     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
00762     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_SETTINGS );
00763 }
00764 
00765 
00766 //------------------------------------------------------------------------------
00767 
00768 OUString SAL_CALL SmXMLExportContent_getImplementationName() throw()
00769 {
00770     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
00771 }
00772 
00773 uno::Sequence< OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames()
00774         throw()
00775 {
00776     const OUString aServiceName( EXPORT_SVC_NAME );
00777     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
00778         return aSeq;
00779 }
00780 
00781 uno::Reference< uno::XInterface > SAL_CALL SmXMLExportContent_createInstance(
00782     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
00783     throw( uno::Exception )
00784 {
00785         // #110680#
00786     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
00787         // The EXPORT_OASIS flag is only required to avoid that a transformer is
00788         // chanied in
00789     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_CONTENT );
00790 }
00791 
00792 //------------------------------------------------------------------------------
00793 
00794 // XServiceInfo
00795 // override empty method from parent class
00796 rtl::OUString SAL_CALL SmXMLExport::getImplementationName()
00797     throw(uno::RuntimeException)
00798 {
00799     OUString aTxt;
00800     switch( getExportFlags() )
00801     {
00802         case EXPORT_META:
00803             aTxt = SmXMLExportMeta_getImplementationName();
00804             break;
00805         case EXPORT_SETTINGS:
00806             aTxt = SmXMLExportSettings_getImplementationName();
00807             break;
00808         case EXPORT_CONTENT:
00809             aTxt = SmXMLExportContent_getImplementationName();
00810             break;
00811         case EXPORT_ALL:
00812         default:
00813             aTxt = SmXMLExport_getImplementationName();
00814             break;
00815     }
00816     return aTxt;
00817 }
00818 
00819 // XServiceInfo
00820 // override empty method from parent class
00821 rtl::OUString SAL_CALL SmXMLImport::getImplementationName()
00822     throw(uno::RuntimeException)
00823 {
00824     OUString aTxt;
00825     switch( getImportFlags() )
00826     {
00827         case IMPORT_META:
00828             aTxt = SmXMLImportMeta_getImplementationName();
00829             break;
00830         case IMPORT_SETTINGS:
00831             aTxt = SmXMLImportSettings_getImplementationName();
00832             break;
00833         case IMPORT_ALL:
00834         default:
00835             aTxt = SmXMLImport_getImplementationName();
00836             break;
00837     }
00838     return aTxt;
00839 }
00840 
00841 
00842 sal_Int64 SAL_CALL SmXMLImport::getSomething( const uno::Sequence< sal_Int8 >&
00843     rId ) throw(uno::RuntimeException)
00844 {
00845     if( rId.getLength() == 16 &&
00846         0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
00847         rId.getConstArray(), 16 ) )
00848     return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
00849 
00850     return SvXMLImport::getSomething( rId );
00851 }
00852 
00853 sal_Int64 SAL_CALL SmXMLExport::getSomething( const uno::Sequence< sal_Int8 >&
00854     rId ) throw(uno::RuntimeException)
00855 {
00856     if( rId.getLength() == 16 &&
00857         0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
00858         rId.getConstArray(), 16 ) )
00859     return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
00860 
00861     return SvXMLExport::getSomething( rId );
00862 }
00863 
00864 
00865 void SmXMLImport::endDocument(void)
00866     throw(xml::sax::SAXException, uno::RuntimeException)
00867 {
00868     //Set the resulted tree into the SmDocShell where it belongs
00869     SmNode *pTree;
00870     if (NULL != (pTree = GetTree()))
00871     {
00872         uno::Reference <frame::XModel> xModel = GetModel();
00873         uno::Reference <lang::XUnoTunnel> xTunnel;
00874         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
00875         SmModel *pModel = reinterpret_cast<SmModel *>
00876             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
00877 
00878         if (pModel)
00879         {
00880             SmDocShell *pDocShell =
00881                 static_cast<SmDocShell*>(pModel->GetObjectShell());
00882             pDocShell->SetFormulaTree(pTree);
00883             if (0 == aText.Len())  //If we picked up no annotation text
00884             {
00885                 //Make up some editable text
00886                 aText = pDocShell->GetText();
00887                 pTree->CreateTextFromNode(aText);
00888                 aText.EraseTrailingChars();
00889                 if((aText.GetChar(0) == '{') &&
00890                     (aText.GetChar(aText.Len()-1) == '}'))
00891                 {
00892                     aText.Erase(0,1);
00893                     aText.Erase(aText.Len()-1,1);
00894                 }
00895             }
00896             pDocShell->SetText( String() );
00897 
00898             // Convert symbol names
00899             SmParser &rParser = pDocShell->GetParser();
00900             BOOL bVal = rParser.IsImportSymbolNames();
00901             rParser.SetImportSymbolNames( TRUE );
00902             SmNode *pTmpTree = rParser.Parse( aText );
00903             aText = rParser.GetText();
00904             delete pTmpTree;
00905             rParser.SetImportSymbolNames( bVal );
00906 
00907             pDocShell->SetText( aText );
00908         }
00909         DBG_ASSERT(pModel,"So there *was* a uno problem after all");
00910 
00911         bSuccess = sal_True;
00912     }
00913 
00914     SvXMLImport::endDocument();
00915 }
00916 
00918 sal_Bool SmXMLWrapper::WriteThroughComponent(
00919     Reference<io::XOutputStream> xOutputStream,
00920     Reference<XComponent> xComponent,
00921     Reference<lang::XMultiServiceFactory> & rFactory,
00922     Reference<beans::XPropertySet> & rPropSet,
00923     const sal_Char* pComponentName )
00924 {
00925     DBG_ASSERT(xOutputStream.is(), "I really need an output stream!");
00926     DBG_ASSERT(xComponent.is(), "Need component!");
00927     DBG_ASSERT(NULL != pComponentName, "Need component name!");
00928 
00929     // get component
00930     Reference< io::XActiveDataSource > xSaxWriter(
00931         rFactory->createInstance(
00932             OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
00933         UNO_QUERY );
00934     DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
00935     if(!xSaxWriter.is())
00936         return sal_False;
00937 
00938     // connect XML writer to output stream
00939     xSaxWriter->setOutputStream( xOutputStream );
00940 
00941     // prepare arguments (prepend doc handler to given arguments)
00942     Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
00943 
00944     Sequence<Any> aArgs( 2 );
00945     aArgs[0] <<= xDocHandler;
00946     aArgs[1] <<= rPropSet;
00947 
00948     // get filter component
00949     Reference< document::XExporter > xExporter(
00950         rFactory->createInstanceWithArguments(
00951             OUString::createFromAscii(pComponentName), aArgs), UNO_QUERY);
00952     DBG_ASSERT( xExporter.is(),
00953             "can't instantiate export filter component" );
00954     if( !xExporter.is() )
00955         return sal_False;
00956 
00957 
00958     // connect model and filter
00959     xExporter->setSourceDocument( xComponent );
00960 
00961     // filter!
00962     Reference < XFilter > xFilter( xExporter, UNO_QUERY );
00963     uno::Sequence< PropertyValue > aProps(0);
00964     xFilter->filter( aProps );
00965 
00966     uno::Reference<lang::XUnoTunnel> xFilterTunnel;
00967     xFilterTunnel = uno::Reference<lang::XUnoTunnel>
00968         ( xFilter, uno::UNO_QUERY );
00969     SmXMLExport *pFilter = reinterpret_cast< SmXMLExport * >(
00970                 sal::static_int_cast< sal_uIntPtr >(
00971                 xFilterTunnel->getSomething( SmXMLExport::getUnoTunnelId() )));
00972     return pFilter ? pFilter->GetSuccess() : sal_True;
00973 }
00974 
00976 sal_Bool SmXMLWrapper::WriteThroughComponent(
00977     const Reference < embed::XStorage >& xStorage,
00978     Reference<XComponent> xComponent,
00979     const sal_Char* pStreamName,
00980     Reference<lang::XMultiServiceFactory> & rFactory,
00981     Reference<beans::XPropertySet> & rPropSet,
00982     const sal_Char* pComponentName,
00983     sal_Bool bCompress
00984     )
00985 {
00986     DBG_ASSERT(xStorage.is(), "Need storage!");
00987     DBG_ASSERT(NULL != pStreamName, "Need stream name!");
00988 
00989     // open stream
00990     Reference < io::XStream > xStream;
00991         OUString sStreamName = OUString::createFromAscii(pStreamName);
00992     try
00993     {
00994         xStream = xStorage->openStreamElement( sStreamName,
00995             embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
00996     }
00997     catch ( uno::Exception& )
00998     {
00999         DBG_ERROR( "Can't create output stream in package!" );
01000         return sal_False;
01001     }
01002 
01003     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
01004     OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
01005     uno::Any aAny;
01006     aAny <<= aMime;
01007 
01008     uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
01009     xSet->setPropertyValue( aPropName, aAny );
01010 
01011     if( !bCompress )
01012     {
01013         aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
01014         sal_Bool bFalse = sal_False;
01015         aAny.setValue( &bFalse, ::getBooleanCppuType() );
01016         xSet->setPropertyValue( aPropName, aAny );
01017     }
01018 
01019     // even plain stream must be encrypted in encrypted document
01020     OUString aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
01021     sal_Bool bTrue = sal_True;
01022     aAny.setValue( &bTrue, ::getBooleanCppuType() );
01023     xSet->setPropertyValue( aTmpPropName, aAny );
01024 
01025         // set Base URL
01026         if( rPropSet.is() )
01027         {
01028                 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
01029                 rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
01030         }
01031 
01032     // write the stuff
01033     sal_Bool bRet = WriteThroughComponent( xStream->getOutputStream(), xComponent, rFactory,
01034         rPropSet, pComponentName );
01035 
01036     // stream is closed by SAX parser
01037     //if( bRet )
01038     //    xStream->getOutputStream()->closeOutput();
01039 
01040     return bRet;
01041 }
01042 
01043 sal_Bool SmXMLWrapper::Export(SfxMedium &rMedium)
01044 {
01045     sal_Bool bRet=sal_True;
01046     uno::Reference<lang::XMultiServiceFactory>
01047         xServiceFactory(utl::getProcessServiceFactory());
01048     DBG_ASSERT(xServiceFactory.is(),"got no service manager");
01049 
01050     //Get model
01051     uno::Reference< lang::XComponent > xModelComp(xModel, uno::UNO_QUERY );
01052 
01053     sal_Bool bEmbedded = sal_False;
01054     uno::Reference <lang::XUnoTunnel> xTunnel;
01055     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
01056     SmModel *pModel = reinterpret_cast<SmModel *>
01057         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
01058 
01059     SmDocShell *pDocShell = pModel ?
01060             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
01061     if( pDocShell &&
01062         SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
01063         bEmbedded = sal_True;
01064 
01065     uno::Reference<task::XStatusIndicator> xStatusIndicator;
01066     if (!bEmbedded)
01067     {
01068         if (pDocShell /*&& pDocShell->GetMedium()*/)
01069         {
01070             DBG_ASSERT( pDocShell->GetMedium() == &rMedium,
01071                     "different SfxMedium found" );
01072 
01073             SfxItemSet* pSet = rMedium.GetItemSet();
01074             if (pSet)
01075             {
01076                 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
01077                     pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
01078                 if (pItem)
01079                     pItem->GetValue() >>= xStatusIndicator;
01080             }
01081         }
01082 
01083         // set progress range and start status indicator
01084         if (xStatusIndicator.is())
01085         {
01086             sal_Int32 nProgressRange = bFlat ? 1 : 3;
01087             xStatusIndicator->start(String(SmResId(STR_STATSTR_WRITING)),
01088                 nProgressRange);
01089         }
01090     }
01091 
01092 
01093         // create XPropertySet with three properties for status indicator
01094         comphelper::PropertyMapEntry aInfoMap[] =
01095         {
01096                 { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
01097                           &::getBooleanCppuType(),
01098                           beans::PropertyAttribute::MAYBEVOID, 0},
01099                 { "BaseURI", sizeof("BaseURI")-1, 0,
01100                           &::getCppuType( (OUString *)0 ),
01101                           beans::PropertyAttribute::MAYBEVOID, 0 },
01102                 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
01103                           &::getCppuType( (OUString *)0 ),
01104                           beans::PropertyAttribute::MAYBEVOID, 0 },
01105                 { "StreamName", sizeof("StreamName")-1, 0,
01106                           &::getCppuType( (OUString *)0 ),
01107                           beans::PropertyAttribute::MAYBEVOID, 0 },
01108                 { NULL, 0, 0, NULL, 0, 0 }
01109         };
01110         uno::Reference< beans::XPropertySet > xInfoSet(
01111                                 comphelper::GenericPropertySet_CreateInstance(
01112                                                         new comphelper::PropertySetInfo( aInfoMap ) ) );
01113 
01114         SvtSaveOptions aSaveOpt;
01115         OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
01116         sal_Bool bUsePrettyPrinting( bFlat || aSaveOpt.IsPrettyPrinting() );
01117         Any aAny;
01118         aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
01119         xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
01120 
01121         // Set base URI
01122         OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
01123     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL( true ) ) );
01124 
01125     sal_Int32 nSteps=0;
01126     if (xStatusIndicator.is())
01127             xStatusIndicator->setValue(nSteps++);
01128     if (!bFlat) //Storage (Package) of Stream
01129     {
01130         uno::Reference < embed::XStorage > xStg = rMedium.GetOutputStorage();
01131                 sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
01132 
01133                 // TODO/LATER: handle the case of embedded links gracefully
01134                 if( bEmbedded ) //&& !pStg->IsRoot() )
01135                 {
01136                         OUString aName;
01137                         if ( rMedium.GetItemSet() )
01138                         {
01139                                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
01140                         rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
01141                                 if ( pDocHierarchItem )
01142                                         aName = pDocHierarchItem->GetValue();
01143                         }
01144 
01145                         if( aName.getLength() )
01146                         {
01147                                 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
01148                                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
01149                         }
01150                 }
01151 
01152                 if( !bEmbedded )
01153         {
01154             if (xStatusIndicator.is())
01155                 xStatusIndicator->setValue(nSteps++);
01156 
01157                         bRet = WriteThroughComponent(
01158                                         xStg, xModelComp, "meta.xml", xServiceFactory, xInfoSet,
01159                                         (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaExporter"
01160                                                         : "com.sun.star.comp.Math.XMLMetaExporter"),
01161                                         sal_False);
01162         }
01163         if( bRet )
01164         {
01165            if (xStatusIndicator.is())
01166                 xStatusIndicator->setValue(nSteps++);
01167 
01168             bRet = WriteThroughComponent(
01169                     xStg, xModelComp, "content.xml", xServiceFactory, xInfoSet,
01170                     "com.sun.star.comp.Math.XMLContentExporter");
01171         }
01172 
01173         if( bRet )
01174         {
01175             if (xStatusIndicator.is())
01176                 xStatusIndicator->setValue(nSteps++);
01177 
01178             bRet = WriteThroughComponent(
01179                     xStg, xModelComp, "settings.xml", xServiceFactory, xInfoSet,
01180                                         (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
01181                                 : "com.sun.star.comp.Math.XMLSettingsExporter") );
01182         }
01183     }
01184     else
01185     {
01186         SvStream *pStream = rMedium.GetOutStream();
01187         uno::Reference<io::XOutputStream> xOut(
01188             new utl::OOutputStreamWrapper(*pStream) );
01189 
01190         if (xStatusIndicator.is())
01191             xStatusIndicator->setValue(nSteps++);
01192 
01193         bRet = WriteThroughComponent(
01194             xOut, xModelComp, xServiceFactory, xInfoSet,
01195             "com.sun.star.comp.Math.XMLContentExporter");
01196     }
01197 
01198     if (xStatusIndicator.is())
01199         xStatusIndicator->end();
01200 
01201     return bRet;
01202 }
01203 
01204 sal_uInt32 SmXMLExport::exportDoc(enum XMLTokenEnum eClass)
01205 {
01206     if( (getExportFlags() & EXPORT_CONTENT) == 0 )
01207     {
01208         SvXMLExport::exportDoc( eClass );
01209     }
01210     else
01211     {
01212         uno::Reference <frame::XModel> xModel = GetModel();
01213         uno::Reference <lang::XUnoTunnel> xTunnel;
01214         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
01215         SmModel *pModel = reinterpret_cast<SmModel *>
01216             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
01217 
01218         if (pModel)
01219         {
01220             SmDocShell *pDocShell =
01221                 static_cast<SmDocShell*>(pModel->GetObjectShell());
01222             pTree = pDocShell->GetFormulaTree();
01223             aText = pDocShell->GetText();
01224         }
01225 
01226         GetDocHandler()->startDocument();
01227 
01228                 if( (getExportFlags() & EXPORT_NODOCTYPE) == 0 &&
01229                         GetExtDocHandler().is() )
01230                 {
01231                         OUString aDocType( RTL_CONSTASCII_USTRINGPARAM( "<!DOCTYPE math:math PUBLIC \"-//OpenOffice.org//DTD Modified W3C MathML 1.01//EN\" \"math.dtd\">" ) );
01232                         GetExtDocHandler()->unknown( aDocType );
01233                 }
01234 
01235         /*Add xmlns line*/
01236         SvXMLAttributeList &rList = GetAttrList();
01237         rList.AddAttribute(GetNamespaceMap().GetAttrNameByKey(
01238             XML_NAMESPACE_MATH_IDX),GetNamespaceMap().GetNameByKey(
01239             XML_NAMESPACE_MATH_IDX));
01240 
01241         //I think we need something like ImplExportEntities();
01242         _ExportContent();
01243         GetDocHandler()->endDocument();
01244     }
01245 
01246     bSuccess=sal_True;
01247     return 0;
01248 }
01249 
01250 class SmXMLImportContext: public SvXMLImportContext
01251 {
01252 public:
01253     SmXMLImportContext( SmXMLImport &rImport, sal_uInt16 nPrfx,
01254         const OUString& rLName)
01255         : SvXMLImportContext(rImport, nPrfx, rLName) {}
01256     const SmXMLImport& GetSmImport() const
01257     {
01258         return (const SmXMLImport&)GetImport();
01259     }
01260     SmXMLImport& GetSmImport()
01261     {
01262         return (SmXMLImport&)GetImport();
01263     }
01264     virtual void TCharacters(const OUString & /*rChars*/) {}
01265     virtual void Characters(const OUString &rChars)
01266     {
01267         /*
01268         Whitespace occurring within the content of token elements is "trimmed"
01269         from the ends (i.e. all whitespace at the beginning and end of the
01270         content is removed), and "collapsed" internally (i.e. each sequence of
01271         1 or more whitespace characters is replaced with one blank character).
01272         */
01273         //collapsing not done yet!
01274         const OUString &rChars2 = rChars.trim();
01275         if (rChars2.getLength())
01276             TCharacters(rChars2/*.collapse()*/);
01277     }
01278     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 /*nPrefix*/,
01279         const OUString& /*rLocalName*/,
01280         const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/) {return 0;}
01281 };
01282 
01283 class SmXMLDocContext_Impl : public SmXMLImportContext
01284 {
01285 public:
01286     SmXMLDocContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
01287         const OUString& rLName)
01288         : SmXMLImportContext(rImport,nPrfx,rLName) {}
01289     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
01290         const OUString& rLocalName,
01291         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
01292     void EndElement();
01293 };
01294 
01295 
01296 /*avert thy gaze from the proginator*/
01297 class SmXMLRowContext_Impl : public SmXMLDocContext_Impl
01298 {
01299 public:
01300     SmXMLRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01301         const OUString& rLName)
01302         : SmXMLDocContext_Impl(rImport,nPrefix,rLName)
01303         { nElementCount = GetSmImport().GetNodeStack().Count(); }
01304     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
01305         const OUString& rLocalName,
01306         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
01307     SvXMLImportContext *StrictCreateChildContext(sal_uInt16 nPrefix,
01308         const OUString& rLocalName,
01309         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
01310     void EndElement();
01311 protected:
01312     ULONG nElementCount;
01313 };
01314 
01315 class SmXMLFracContext_Impl : public SmXMLRowContext_Impl
01316 {
01317 public:
01318     SmXMLFracContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01319         const OUString& rLName)
01320         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01321     void EndElement();
01322 };
01323 
01324 class SmXMLSqrtContext_Impl : public SmXMLRowContext_Impl
01325 {
01326 public:
01327     SmXMLSqrtContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01328         const OUString& rLName)
01329         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01330     void EndElement();
01331 };
01332 
01333 class SmXMLRootContext_Impl : public SmXMLRowContext_Impl
01334 {
01335 public:
01336     SmXMLRootContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01337         const OUString& rLName)
01338         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01339     void EndElement();
01340 };
01341 
01342 struct SmXMLContext_Helper
01343 {
01344     SmXMLContext_Helper(SmXMLImportContext &rImport) : 
01345         nIsBold(-1), nIsItalic(-1),nFontSize(0.0), rContext(rImport)  {}
01346     
01347     void RetrieveAttrs(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
01348     void ApplyAttrs();
01349 
01350     sal_Int8 nIsBold;
01351     sal_Int8 nIsItalic;
01352     double nFontSize;
01353     sal_Bool bFontNodeNeeded;
01354     OUString sFontFamily;
01355     OUString sColor;
01356 
01357     SmXMLImportContext rContext;
01358 };
01359 
01360 void SmXMLContext_Helper::RetrieveAttrs(const uno::Reference<
01361     xml::sax::XAttributeList > & xAttrList )
01362 {
01363     sal_Int8 nOldIsBold=nIsBold;
01364     sal_Int8 nOldIsItalic=nIsItalic;
01365     double nOldFontSize=nFontSize;
01366     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
01367     OUString sOldFontFamily = sFontFamily;
01368     for (sal_Int16 i=0;i<nAttrCount;i++)
01369     {
01370         OUString sAttrName = xAttrList->getNameByIndex(i);
01371         OUString aLocalName;
01372         sal_uInt16 nPrefix = rContext.GetSmImport().GetNamespaceMap().
01373             GetKeyByAttrName(sAttrName,&aLocalName);
01374         OUString sValue = xAttrList->getValueByIndex(i);
01375         const SvXMLTokenMap &rAttrTokenMap =
01376             rContext.GetSmImport().GetPresLayoutAttrTokenMap();
01377         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
01378         {
01379             case XML_TOK_FONTWEIGHT:
01380                 nIsBold = sValue.equals(GetXMLToken(XML_BOLD));
01381                 break;
01382             case XML_TOK_FONTSTYLE:
01383                 nIsItalic = sValue.equals(GetXMLToken(XML_ITALIC));
01384                 break;
01385             case XML_TOK_FONTSIZE:
01386                 SvXMLUnitConverter::convertDouble(nFontSize,sValue);
01387                 rContext.GetSmImport().GetMM100UnitConverter().
01388                     setXMLMeasureUnit(MAP_POINT);
01389                 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
01390                     if (-1 == sValue.indexOf('%'))
01391                         nFontSize=0.0;
01392                     else
01393                     {
01394                         rContext.GetSmImport().GetMM100UnitConverter().
01395                             setXMLMeasureUnit(MAP_RELATIVE);
01396                     }
01397                 break;
01398             case XML_TOK_FONTFAMILY:
01399                 sFontFamily = sValue;
01400                 break;
01401             case XML_TOK_COLOR:
01402                 sColor = sValue;
01403                 break;
01404             default:
01405                 break;
01406         }
01407     }
01408 
01409     if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
01410         (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
01411         || sColor.getLength())
01412         bFontNodeNeeded=sal_True;
01413     else
01414         bFontNodeNeeded=sal_False;
01415 }
01416 
01417 void SmXMLContext_Helper::ApplyAttrs()
01418 {
01419     SmNodeStack &rNodeStack = rContext.GetSmImport().GetNodeStack();
01420 
01421     if (bFontNodeNeeded)
01422     {
01423         SmToken aToken;
01424         aToken.cMathChar = '\0';
01425         aToken.nGroup = 0;
01426         aToken.nLevel = 5;
01427 
01428         if (nIsBold != -1)
01429         {
01430             if (nIsBold)
01431                 aToken.eType = TBOLD;
01432             else
01433                 aToken.eType = TNBOLD;
01434             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
01435                 (new SmFontNode(aToken));
01436             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01437             rNodeStack.Push(pFontNode);
01438         }
01439         if (nIsItalic != -1)
01440         {
01441             if (nIsItalic)
01442                 aToken.eType = TITALIC;
01443             else
01444                 aToken.eType = TNITALIC;
01445             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
01446                 (new SmFontNode(aToken));
01447             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01448             rNodeStack.Push(pFontNode);
01449         }
01450         if (nFontSize != 0.0)
01451         {
01452             aToken.eType = TSIZE;
01453             SmFontNode *pFontNode = new SmFontNode(aToken);
01454 
01455             if (MAP_RELATIVE == rContext.GetSmImport().GetMM100UnitConverter().
01456                 getXMLMeasureUnit())
01457             {
01458                 if (nFontSize < 100.00)
01459                     pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
01460                         FNTSIZ_DIVIDE);
01461                 else
01462                     pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
01463                         FNTSIZ_MULTIPLY);
01464             }
01465             else
01466                 pFontNode->SetSizeParameter(Fraction(nFontSize),FNTSIZ_ABSOLUT);
01467 
01468             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01469             rNodeStack.Push(pFontNode);
01470         }
01471         if (sFontFamily.getLength())
01472         {
01473             if (sFontFamily.equalsIgnoreAsciiCase(GetXMLToken(XML_FIXED)))
01474                 aToken.eType = TFIXED;
01475             else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
01476                 RTL_CONSTASCII_USTRINGPARAM("sans"))))
01477                 aToken.eType = TSANS;
01478             else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
01479                 RTL_CONSTASCII_USTRINGPARAM("serif"))))
01480                 aToken.eType = TSERIF;
01481             else //Just give up, we need to extend our font mechanism to be
01482                 //more general
01483                 return;
01484 
01485             aToken.aText = sFontFamily;
01486             SmFontNode *pFontNode = new SmFontNode(aToken);
01487             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01488             rNodeStack.Push(pFontNode);
01489         }
01490         if (sColor.getLength())
01491         {
01492             //Again we can only handle a small set of colours in
01493             //StarMath for now.
01494             const SvXMLTokenMap& rTokenMap =
01495                 rContext.GetSmImport().GetColorTokenMap();
01496             aToken.eType = static_cast<SmTokenType>(rTokenMap.Get(
01497                 XML_NAMESPACE_MATH, sColor));
01498             if (aToken.eType != -1)
01499             {
01500                 SmFontNode *pFontNode = new SmFontNode(aToken);
01501                 pFontNode->SetSubNodes(0,rNodeStack.Pop());
01502                 rNodeStack.Push(pFontNode);
01503             }
01504         }
01505 
01506     }
01507 }
01508 
01509 class SmXMLStyleContext_Impl : public SmXMLRowContext_Impl
01510 {
01511 public:
01512     /*Right now the style tag is completely ignored*/
01513     SmXMLStyleContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01514         const OUString& rLName) : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
01515         aStyleHelper(*this) {}
01516     void EndElement();
01517     void StartElement(const uno::Reference< xml::sax::XAttributeList > &
01518         xAttrList );
01519 protected:
01520     SmXMLContext_Helper aStyleHelper;
01521 };
01522 
01523 void SmXMLStyleContext_Impl::StartElement(const uno::Reference<
01524     xml::sax::XAttributeList > & xAttrList )
01525 {
01526 #if 1
01527     aStyleHelper.RetrieveAttrs(xAttrList);
01528 #else
01529     sal_Int8 nOldIsBold=nIsBold;
01530     sal_Int8 nOldIsItalic=nIsItalic;
01531     double nOldFontSize=nFontSize;
01532     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
01533     OUString sOldFontFamily = sFontFamily;
01534     for (sal_Int16 i=0;i<nAttrCount;i++)
01535     {
01536         OUString sAttrName = xAttrList->getNameByIndex(i);
01537         OUString aLocalName;
01538         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
01539             GetKeyByAttrName(sAttrName,&aLocalName);
01540         OUString sValue = xAttrList->getValueByIndex(i);
01541         const SvXMLTokenMap &rAttrTokenMap =
01542             GetSmImport().GetPresLayoutAttrTokenMap();
01543         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
01544         {
01545             case XML_TOK_FONTWEIGHT:
01546                 nIsBold = sValue.equals(GetXMLToken(XML_BOLD));
01547                 break;
01548             case XML_TOK_FONTSTYLE:
01549                 nIsItalic = sValue.equals(GetXMLToken(XML_ITALIC));
01550                 break;
01551             case XML_TOK_FONTSIZE:
01552                 SvXMLUnitConverter::convertDouble(nFontSize,sValue);
01553                 GetSmImport().GetMM100UnitConverter().
01554                     setXMLMeasureUnit(MAP_POINT);
01555                 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
01556                     if (-1 == sValue.indexOf('%'))
01557                         nFontSize=0.0;
01558                     else
01559                     {
01560                         GetSmImport().GetMM100UnitConverter().
01561                             setXMLMeasureUnit(MAP_RELATIVE);
01562                     }
01563                 break;
01564             case XML_TOK_FONTFAMILY:
01565                 sFontFamily = sValue;
01566                 break;
01567             case XML_TOK_COLOR:
01568                 sColor = sValue;
01569                 break;
01570             default:
01571                 break;
01572         }
01573     }
01574 
01575     if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
01576         (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
01577         || sColor.getLength())
01578         bFontNodeNeeded=sal_True;
01579     else
01580         bFontNodeNeeded=sal_False;
01581 #endif
01582 }
01583 
01584 
01585 void SmXMLStyleContext_Impl::EndElement()
01586 {
01587     /*
01588     <mstyle> accepts any number of arguments; if this number is not 1, its
01589     contents are treated as a single "inferred <mrow>" containing its
01590     arguments
01591     */
01592     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
01593     if (rNodeStack.Count() - nElementCount > 1)
01594         SmXMLRowContext_Impl::EndElement();
01595 #if 1
01596     aStyleHelper.ApplyAttrs();
01597 #else
01598     if (bFontNodeNeeded)
01599     {
01600         SmToken aToken;
01601         aToken.cMathChar = '\0';
01602         aToken.nGroup = 0;
01603         aToken.nLevel = 5;
01604 
01605         if (nIsBold != -1)
01606         {
01607             if (nIsBold)
01608                 aToken.eType = TBOLD;
01609             else
01610                 aToken.eType = TNBOLD;
01611             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
01612                 (new SmFontNode(aToken));
01613             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01614             rNodeStack.Push(pFontNode);
01615         }
01616         if (nIsItalic != -1)
01617         {
01618             if (nIsItalic)
01619                 aToken.eType = TITALIC;
01620             else
01621                 aToken.eType = TNITALIC;
01622             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
01623                 (new SmFontNode(aToken));
01624             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01625             rNodeStack.Push(pFontNode);
01626         }
01627         if (nFontSize != 0.0)
01628         {
01629             aToken.eType = TSIZE;
01630             SmFontNode *pFontNode = new SmFontNode(aToken);
01631 
01632             if (MAP_RELATIVE == GetSmImport().GetMM100UnitConverter().
01633                 getXMLMeasureUnit())
01634             {
01635                 if (nFontSize < 100.00)
01636                     pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
01637                         FNTSIZ_DIVIDE);
01638                 else
01639                     pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
01640                         FNTSIZ_MULTIPLY);
01641             }
01642             else
01643                 pFontNode->SetSizeParameter(Fraction(nFontSize),FNTSIZ_ABSOLUT);
01644 
01645             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01646             rNodeStack.Push(pFontNode);
01647         }
01648         if (sFontFamily.getLength())
01649         {
01650             if (sFontFamily.equalsIgnoreCase(GetXMLToken(XML_FIXED)))
01651                 aToken.eType = TFIXED;
01652             else if (sFontFamily.equalsIgnoreCase(OUString(
01653                 RTL_CONSTASCII_USTRINGPARAM("sans"))))
01654                 aToken.eType = TSANS;
01655             else if (sFontFamily.equalsIgnoreCase(OUString(
01656                 RTL_CONSTASCII_USTRINGPARAM("serif"))))
01657                 aToken.eType = TSERIF;
01658             else //Just give up, we need to extend our font mechanism to be
01659                 //more general
01660                 return;
01661 
01662             aToken.aText = sFontFamily;
01663             SmFontNode *pFontNode = new SmFontNode(aToken);
01664             pFontNode->SetSubNodes(0,rNodeStack.Pop());
01665             rNodeStack.Push(pFontNode);
01666         }
01667         if (sColor.getLength())
01668         {
01669             //Again we can only handle a small set of colours in
01670             //StarMath for now.
01671             const SvXMLTokenMap& rTokenMap =
01672                 GetSmImport().GetColorTokenMap();
01673             aToken.eType = static_cast<SmTokenType>(rTokenMap.Get(
01674                 XML_NAMESPACE_MATH, sColor));
01675             if (aToken.eType != -1)
01676             {
01677                 SmFontNode *pFontNode = new SmFontNode(aToken);
01678                 pFontNode->SetSubNodes(0,rNodeStack.Pop());
01679                 rNodeStack.Push(pFontNode);
01680             }
01681         }
01682 
01683     }
01684 #endif
01685 }
01686 
01687 class SmXMLPaddedContext_Impl : public SmXMLRowContext_Impl
01688 {
01689 public:
01690     /*Right now the style tag is completely ignored*/
01691     SmXMLPaddedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01692         const OUString& rLName)
01693         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01694     void EndElement();
01695 };
01696 
01697 void SmXMLPaddedContext_Impl::EndElement()
01698 {
01699     /*
01700     <mpadded> accepts any number of arguments; if this number is not 1, its
01701     contents are treated as a single "inferred <mrow>" containing its
01702     arguments
01703     */
01704     if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
01705         SmXMLRowContext_Impl::EndElement();
01706 }
01707 
01708 class SmXMLPhantomContext_Impl : public SmXMLRowContext_Impl
01709 {
01710 public:
01711     /*Right now the style tag is completely ignored*/
01712     SmXMLPhantomContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01713         const OUString& rLName)
01714         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01715     void EndElement();
01716 };
01717 
01718 void SmXMLPhantomContext_Impl::EndElement()
01719 {
01720     /*
01721     <mphantom> accepts any number of arguments; if this number is not 1, its
01722     contents are treated as a single "inferred <mrow>" containing its
01723     arguments
01724     */
01725     if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
01726         SmXMLRowContext_Impl::EndElement();
01727 
01728     SmToken aToken;
01729     aToken.cMathChar = '\0';
01730     aToken.nGroup = 0;
01731     aToken.nLevel = 5;
01732     aToken.eType = TPHANTOM;
01733 
01734     SmStructureNode *pPhantom = static_cast<SmStructureNode *>
01735         (new SmFontNode(aToken));
01736     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
01737     pPhantom->SetSubNodes(0,rNodeStack.Pop());
01738     rNodeStack.Push(pPhantom);
01739 }
01740 
01741 class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
01742 {
01743 public:
01744     SmXMLFencedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01745         const OUString& rLName)
01746         : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
01747         cBegin('('), cEnd(')') {}
01748     void StartElement(const uno::Reference<
01749         xml::sax::XAttributeList > & xAttrList );
01750     void EndElement();
01751 protected:
01752     sal_Unicode cBegin;
01753     sal_Unicode cEnd;
01754 };
01755 
01756 
01757 void SmXMLFencedContext_Impl::StartElement(const uno::Reference<
01758     xml::sax::XAttributeList > & xAttrList )
01759 {
01760     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
01761     for (sal_Int16 i=0;i<nAttrCount;i++)
01762     {
01763         OUString sAttrName = xAttrList->getNameByIndex(i);
01764         OUString aLocalName;
01765         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
01766             GetKeyByAttrName(sAttrName,&aLocalName);
01767         OUString sValue = xAttrList->getValueByIndex(i);
01768         const SvXMLTokenMap &rAttrTokenMap =
01769             GetSmImport().GetFencedAttrTokenMap();
01770         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
01771         {
01772             //temp, starmath cannot handle multichar brackets (I think)
01773             case XML_TOK_OPEN:
01774                 cBegin = sValue[0];
01775                 break;
01776             case XML_TOK_CLOSE:
01777                 cEnd = sValue[0];
01778                 break;
01779             default:
01780                 /*Go to superclass*/
01781                 break;
01782         }
01783     }
01784 }
01785 
01786 
01787 void SmXMLFencedContext_Impl::EndElement()
01788 {
01789     SmToken aToken;
01790     aToken.cMathChar = '\0';
01791     aToken.nGroup = 0;
01792     aToken.aText = ',';
01793     aToken.eType = TLEFT;
01794     aToken.nLevel = 5;
01795 
01796     aToken.eType = TLPARENT;
01797     aToken.cMathChar = cBegin;
01798     SmStructureNode *pSNode = new SmBraceNode(aToken);
01799     SmNode *pLeft = new SmMathSymbolNode(aToken);
01800 
01801     aToken.cMathChar = cEnd;
01802     aToken.eType = TRPARENT;
01803     SmNode *pRight = new SmMathSymbolNode(aToken);
01804 
01805     SmNodeArray aRelationArray;
01806     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
01807 
01808     aToken.cMathChar = '\0';
01809     aToken.aText = ',';
01810     aToken.eType = TIDENT;
01811 
01812     ULONG i=rNodeStack.Count()-nElementCount;
01813     if (rNodeStack.Count()-nElementCount > 1)
01814         i+=rNodeStack.Count()-1-nElementCount;
01815     aRelationArray.SetSize(i);
01816     while(rNodeStack.Count() > nElementCount)
01817     {
01818         aRelationArray.Put(--i,rNodeStack.Pop());
01819         if (rNodeStack.Count() > 1)
01820             aRelationArray.Put(--i,new SmGlyphSpecialNode(aToken));
01821     }
01822 
01823     SmToken aDummy;
01824     SmStructureNode *pBody = new SmExpressionNode(aDummy);
01825     pBody->SetSubNodes(aRelationArray);
01826 
01827 
01828     pSNode->SetSubNodes(pLeft,pBody,pRight);
01829     pSNode->SetScaleMode(SCALE_HEIGHT);
01830     GetSmImport().GetNodeStack().Push(pSNode);
01831 }
01832 
01833 
01834 class SmXMLErrorContext_Impl : public SmXMLRowContext_Impl
01835 {
01836 public:
01837     SmXMLErrorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01838         const OUString& rLName)
01839         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
01840     void EndElement();
01841 };
01842 
01843 void SmXMLErrorContext_Impl::EndElement()
01844 {
01845     /*Right now the error tag is completely ignored, what
01846      can I do with it in starmath, ?, maybe we need a
01847      report window ourselves, do a test for validity of
01848      the xml input, use merrors, and then generate
01849      the markup inside the merror with a big red colour
01850      of something. For now just throw them all away.
01851      */
01852     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
01853     while(rNodeStack.Count() > nElementCount)
01854     {
01855         SmNode *pNode = rNodeStack.Pop();
01856         delete pNode;
01857     }
01858 }
01859 
01860 class SmXMLNumberContext_Impl : public SmXMLImportContext
01861 {
01862 public:
01863     SmXMLNumberContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01864         const OUString& rLName)
01865         : SmXMLImportContext(rImport,nPrefix,rLName)
01866     {
01867         aToken.cMathChar = '\0';
01868         aToken.nGroup = 0;
01869         aToken.nLevel = 5;
01870         aToken.eType = TNUMBER;
01871     }
01872     virtual void TCharacters(const OUString &rChars);
01873     void EndElement();
01874 protected:
01875     SmToken aToken;
01876 };
01877 
01878 void SmXMLNumberContext_Impl::TCharacters(const OUString &rChars)
01879 {
01880     aToken.aText = rChars;
01881 }
01882 
01883 void SmXMLNumberContext_Impl::EndElement()
01884 {
01885     GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_NUMBER));
01886 }
01887 
01888 class SmXMLAnnotationContext_Impl : public SmXMLImportContext
01889 {
01890 public:
01891     SmXMLAnnotationContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01892         const OUString& rLName)
01893         : SmXMLImportContext(rImport,nPrefix,rLName), bIsStarMath(sal_False) {}
01894     virtual void Characters(const OUString &rChars);
01895     void StartElement(const uno::Reference<xml::sax::XAttributeList > &
01896         xAttrList );
01897 private:
01898     sal_Bool bIsStarMath;
01899 };
01900 
01901 void SmXMLAnnotationContext_Impl::StartElement(const uno::Reference<
01902     xml::sax::XAttributeList > & xAttrList )
01903 {
01904     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
01905     for (sal_Int16 i=0;i<nAttrCount;i++)
01906     {
01907         OUString sAttrName = xAttrList->getNameByIndex(i);
01908         OUString aLocalName;
01909         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
01910             GetKeyByAttrName(sAttrName,&aLocalName);
01911 
01912         OUString sValue = xAttrList->getValueByIndex(i);
01913         const SvXMLTokenMap &rAttrTokenMap =
01914             GetSmImport().GetAnnotationAttrTokenMap();
01915         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
01916         {
01917             case XML_TOK_ENCODING:
01918                 bIsStarMath= sValue.equals(
01919                     OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
01920                 break;
01921             default:
01922                 break;
01923         }
01924     }
01925 }
01926 
01927 void SmXMLAnnotationContext_Impl::Characters(const OUString &rChars)
01928 {
01929     if (bIsStarMath)
01930         GetSmImport().GetText().Append(String(rChars));
01931 }
01932 
01933 class SmXMLTextContext_Impl : public SmXMLImportContext
01934 {
01935 public:
01936     SmXMLTextContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01937         const OUString& rLName)
01938         : SmXMLImportContext(rImport,nPrefix,rLName)
01939     {
01940         aToken.cMathChar = '\0';
01941         aToken.nGroup = 0;
01942         aToken.nLevel = 5;
01943         aToken.eType = TTEXT;
01944     }
01945     virtual void TCharacters(const OUString &rChars);
01946     void EndElement();
01947 protected:
01948     SmToken aToken;
01949 };
01950 
01951 void SmXMLTextContext_Impl::TCharacters(const OUString &rChars)
01952 {
01953     aToken.aText = rChars;
01954 }
01955 
01956 void SmXMLTextContext_Impl::EndElement()
01957 {
01958     GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_TEXT));
01959 }
01960 
01961 class SmXMLStringContext_Impl : public SmXMLImportContext
01962 {
01963 public:
01964     SmXMLStringContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
01965         const OUString& rLName)
01966         : SmXMLImportContext(rImport,nPrefix,rLName)
01967     {
01968         aToken.cMathChar = '\0';
01969         aToken.nGroup = 0;
01970         aToken.nLevel = 5;
01971         aToken.eType = TTEXT;
01972     }
01973     virtual void TCharacters(const OUString &rChars);
01974     void EndElement();
01975 protected:
01976     SmToken aToken;
01977 };
01978 
01979 void SmXMLStringContext_Impl::TCharacters(const OUString &rChars)
01980 {
01981     /*
01982     The content of <ms> elements should be rendered with visible "escaping" of
01983     certain characters in the content, including at least "double quote"
01984     itself, and preferably whitespace other than individual blanks. The intent
01985     is for the viewer to see that the expression is a string literal, and to
01986     see exactly which characters form its content. For example, <ms>double
01987     quote is "</ms> might be rendered as "double quote is \"".
01988 
01989     Obviously this isn't fully done here.
01990     */
01991     aToken.aText.Erase();
01992     aToken.aText += '\"';
01993     aToken.aText += String(rChars);
01994     aToken.aText += '\"';
01995 }
01996 
01997 void SmXMLStringContext_Impl::EndElement()
01998 {
01999     GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_FIXED));
02000 }
02001 
02002 class SmXMLIdentifierContext_Impl : public SmXMLImportContext
02003 {
02004 public:
02005     SmXMLIdentifierContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02006         const OUString& rLName)
02007         : SmXMLImportContext(rImport,nPrefix,rLName),aStyleHelper(*this)
02008     {
02009         aToken.cMathChar = '\0';
02010         aToken.nGroup = 0;
02011         aToken.nLevel = 5;
02012         aToken.eType = TIDENT;
02013     }
02014     void TCharacters(const OUString &rChars);
02015     void StartElement(const uno::Reference<
02016     xml::sax::XAttributeList > & xAttrList ) {aStyleHelper.RetrieveAttrs(xAttrList);};
02017     void EndElement();
02018 protected:
02019     SmXMLContext_Helper aStyleHelper;
02020     SmToken aToken;
02021 };
02022 
02023 void SmXMLIdentifierContext_Impl::EndElement()
02024 {
02025     SmTextNode *pNode = 0;
02026     //we will handle identifier italic/normal here instead of with a standalone
02027     //font node
02028     if (((aStyleHelper.nIsItalic == -1) && (aToken.aText.Len() > 1))
02029         || ((aStyleHelper.nIsItalic == 0) && (aToken.aText.Len() == 1)))
02030     {
02031         pNode = new SmTextNode(aToken,FNT_FUNCTION);
02032         pNode->GetFont().SetItalic(ITALIC_NONE);
02033         aStyleHelper.nIsItalic = -1;
02034     }
02035     else
02036         pNode = new SmTextNode(aToken,FNT_VARIABLE);
02037     if (aStyleHelper.bFontNodeNeeded && aStyleHelper.nIsItalic != -1)
02038     {
02039         if (aStyleHelper.nIsItalic)
02040             pNode->GetFont().SetItalic(ITALIC_NORMAL);
02041         else
02042             pNode->GetFont().SetItalic(ITALIC_NONE);
02043     }
02044 
02045     if ((-1!=aStyleHelper.nIsBold) || (0.0!=aStyleHelper.nFontSize) ||
02046         (aStyleHelper.sFontFamily.getLength()) ||
02047         aStyleHelper.sColor.getLength())
02048         aStyleHelper.bFontNodeNeeded=sal_True;
02049     else
02050         aStyleHelper.bFontNodeNeeded=sal_False;
02051     if (aStyleHelper.bFontNodeNeeded)
02052         aStyleHelper.ApplyAttrs();
02053     GetSmImport().GetNodeStack().Push(pNode);
02054 }
02055 
02056 void SmXMLIdentifierContext_Impl::TCharacters(const OUString &rChars)
02057 {
02058     aToken.aText = rChars;
02059 }
02060 
02061 class SmXMLOperatorContext_Impl : public SmXMLImportContext
02062 {
02063 public:
02064     SmXMLOperatorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02065         const OUString& rLName)
02066         : SmXMLImportContext(rImport,nPrefix,rLName), bIsStretchy(sal_False)
02067     {
02068         aToken.nGroup = 0;
02069         aToken.eType = TSPECIAL;
02070         aToken.nLevel = 5;
02071     }
02072     void TCharacters(const OUString &rChars);
02073     void StartElement(const uno::Reference<
02074         xml::sax::XAttributeList > &xAttrList );
02075     void EndElement();
02076 protected:
02077     SmToken aToken;
02078 private:
02079     sal_Bool bIsStretchy;
02080 };
02081 
02082 void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
02083 {
02084     aToken.cMathChar = rChars[0];
02085 }
02086 
02087 void SmXMLOperatorContext_Impl::EndElement()
02088 {
02089     SmMathSymbolNode *pNode = new SmMathSymbolNode(aToken);
02090     //For stretchy scaling the scaling must be retrieved from this node
02091     //and applied to the expression itself so as to get the expression
02092     //to scale the operator to the height of the expression itself
02093     if (bIsStretchy)
02094         pNode->SetScaleMode(SCALE_HEIGHT);
02095     GetSmImport().GetNodeStack().Push(pNode);
02096 }
02097 
02098 
02099 
02100 void SmXMLOperatorContext_Impl::StartElement(const uno::Reference<
02101     xml::sax::XAttributeList > & xAttrList )
02102 {
02103     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
02104     for (sal_Int16 i=0;i<nAttrCount;i++)
02105     {
02106         OUString sAttrName = xAttrList->getNameByIndex(i);
02107         OUString aLocalName;
02108         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
02109             GetKeyByAttrName(sAttrName,&aLocalName);
02110 
02111         OUString sValue = xAttrList->getValueByIndex(i);
02112         const SvXMLTokenMap &rAttrTokenMap =
02113             GetSmImport().GetOperatorAttrTokenMap();
02114         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
02115         {
02116             case XML_TOK_STRETCHY:
02117                 bIsStretchy = sValue.equals(
02118                     GetXMLToken(XML_TRUE));
02119                 break;
02120             default:
02121                 break;
02122         }
02123     }
02124 }
02125 
02126 
02127 class SmXMLSpaceContext_Impl : public SmXMLImportContext
02128 {
02129 public:
02130     SmXMLSpaceContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02131         const OUString& rLName)
02132         : SmXMLImportContext(rImport,nPrefix,rLName) {}
02133     void StartElement(const uno::Reference<
02134         xml::sax::XAttributeList >& xAttrList );
02135 };
02136 
02137 void SmXMLSpaceContext_Impl::StartElement(
02138     const uno::Reference<xml::sax::XAttributeList > & /*xAttrList*/ )
02139 {
02140     SmToken aToken;
02141     aToken.cMathChar = '\0';
02142     aToken.nGroup = 0;
02143     aToken.eType = TBLANK;
02144     aToken.nLevel = 5;
02145     SmBlankNode *pBlank = new SmBlankNode(aToken);
02146     pBlank->IncreaseBy(aToken);
02147     GetSmImport().GetNodeStack().Push(pBlank);
02148 }
02149 
02150 class SmXMLSubContext_Impl : public SmXMLRowContext_Impl
02151 {
02152 public:
02153     SmXMLSubContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02154         const OUString& rLName)
02155         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
02156     void EndElement() { GenericEndElement(TRSUB,RSUB); }
02157 protected:
02158     void GenericEndElement(SmTokenType eType,SmSubSup aSubSup);
02159 };
02160 
02161 
02162 void SmXMLSubContext_Impl::GenericEndElement(SmTokenType eType,SmSubSup aSubSup)
02163 {
02164     /*The <msub> element requires exactly 2 arguments.*/
02165     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount == 2,
02166         "Sub has not two arguments");
02167     SmToken aToken;
02168     aToken.cMathChar = '\0';
02169     aToken.nGroup = 0;
02170     aToken.nLevel = 0;
02171     aToken.eType = eType;
02172     SmSubSupNode *pNode = new SmSubSupNode(aToken);
02173     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02174 
02175     // initialize subnodes array
02176     SmNodeArray  aSubNodes;
02177     aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
02178     for (ULONG i = 1;  i < aSubNodes.GetSize();  i++)
02179         aSubNodes.Put(i, NULL);
02180 
02181     aSubNodes.Put(aSubSup+1,rNodeStack.Pop());
02182     aSubNodes.Put(0, rNodeStack.Pop());
02183     pNode->SetSubNodes(aSubNodes);
02184     rNodeStack.Push(pNode);
02185 }
02186 
02187 class SmXMLSupContext_Impl : public SmXMLSubContext_Impl
02188 {
02189 public:
02190     SmXMLSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02191         const OUString& rLName)
02192         : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
02193     void EndElement() {GenericEndElement(TRSUP,RSUP);}
02194 };
02195 
02196 class SmXMLSubSupContext_Impl : public SmXMLRowContext_Impl
02197 {
02198 public:
02199     SmXMLSubSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02200         const OUString& rLName)
02201         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
02202     void EndElement() { GenericEndElement(TRSUB,RSUB,RSUP); }
02203 protected:
02204     void GenericEndElement(SmTokenType eType,
02205         SmSubSup aSub,SmSubSup aSup);
02206 
02207 };
02208 
02209 void SmXMLSubSupContext_Impl::GenericEndElement(SmTokenType eType,
02210         SmSubSup aSub,SmSubSup aSup)
02211 {
02212     /*The <msub> element requires exactly 3 arguments.*/
02213     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount == 3,
02214         "SubSup has not three arguments");
02215 
02216     SmToken aToken;
02217     aToken.cMathChar = '\0';
02218     aToken.nGroup = 0;
02219     aToken.nLevel = 0;
02220     aToken.eType = eType;
02221     SmSubSupNode *pNode = new SmSubSupNode(aToken);
02222     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02223 
02224     // initialize subnodes array
02225     SmNodeArray  aSubNodes;
02226     aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
02227     for (ULONG i = 1;  i < aSubNodes.GetSize();  i++)
02228         aSubNodes.Put(i, NULL);
02229 
02230     aSubNodes.Put(aSup+1,rNodeStack.Pop());
02231     aSubNodes.Put(aSub+1,rNodeStack.Pop());
02232     aSubNodes.Put(0, rNodeStack.Pop());
02233     pNode->SetSubNodes(aSubNodes);
02234     rNodeStack.Push(pNode);
02235 }
02236 
02237 class SmXMLUnderContext_Impl : public SmXMLSubContext_Impl
02238 {
02239 public:
02240     SmXMLUnderContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02241         const OUString& rLName)
02242         : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
02243     void StartElement(const uno::Reference< xml::sax::XAttributeList > &
02244         xAttrList );
02245     void EndElement();
02246     void HandleAccent();
02247 protected:
02248     sal_Int16 nAttrCount;
02249 };
02250 
02251 void SmXMLUnderContext_Impl::StartElement(const uno::Reference<
02252     xml::sax::XAttributeList > & xAttrList )
02253 {
02254     nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
02255 }
02256 
02257 void SmXMLUnderContext_Impl::HandleAccent()
02258 {
02259     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount == 2,
02260         "Sub has not two arguments");
02261 
02262     /*Just one special case for the underline thing*/
02263     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02264     SmNode *pTest = rNodeStack.Pop();
02265     SmToken aToken;
02266     aToken.cMathChar = '\0';
02267     aToken.nGroup = 0;
02268     aToken.nLevel = 0;
02269     aToken.eType = TUNDERLINE;
02270 
02271 
02272     SmNodeArray aSubNodes;
02273     aSubNodes.SetSize(2);
02274 
02275     SmStructureNode *pNode = new SmAttributNode(aToken);
02276     if ((pTest->GetToken().cMathChar & 0x0FFF) == 0x0332)
02277     {
02278         aSubNodes.Put(0, new SmRectangleNode(aToken));
02279         delete pTest;
02280     }
02281     else
02282         aSubNodes.Put(0, pTest);
02283 
02284     aSubNodes.Put(1, rNodeStack.Pop());
02285     pNode->SetSubNodes(aSubNodes);
02286     pNode->SetScaleMode(SCALE_WIDTH);
02287     rNodeStack.Push(pNode);
02288 }
02289 
02290 
02291 void SmXMLUnderContext_Impl::EndElement()
02292 {
02293     if (!nAttrCount)
02294         GenericEndElement(TCSUB,CSUB);
02295     else
02296         HandleAccent();
02297 #if 0
02298     //UnderBrace trick
02299     SmStructureNode *pNode = rNodeStack.Pop();
02300     if (pNode->GetSubNode(1)->GetToken().cMathChar == (0x0332|0xf000))
02301     if (pNode->GetSubNode(0)->GetToken().cMathChar == (0x0332|0xf000))
02302 #endif
02303 }
02304 
02305 class SmXMLOverContext_Impl : public SmXMLSubContext_Impl
02306 {
02307 public:
02308     SmXMLOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02309         const OUString& rLName)
02310         : SmXMLSubContext_Impl(rImport,nPrefix,rLName), nAttrCount(0) {}
02311     void EndElement();
02312     void StartElement(const uno::Reference< xml::sax::XAttributeList > &
02313         xAttrList );
02314     void HandleAccent();
02315 protected:
02316     sal_Int16 nAttrCount;
02317 };
02318 
02319 
02320 void SmXMLOverContext_Impl::StartElement(const uno::Reference<
02321     xml::sax::XAttributeList > & xAttrList )
02322 {
02323     nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
02324 }
02325 
02326 
02327 void SmXMLOverContext_Impl::EndElement()
02328 {
02329     if (!nAttrCount)
02330         GenericEndElement(TCSUP,CSUP);
02331     else
02332         HandleAccent();
02333 }
02334 
02335 
02336 void SmXMLOverContext_Impl::HandleAccent()
02337 {
02338     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount == 2,
02339         "Sub has not two arguments");
02340     SmToken aToken;
02341     aToken.cMathChar = '\0';
02342     aToken.nGroup = 0;
02343     aToken.nLevel = 0;
02344     aToken.eType = TACUTE;
02345 
02346     SmAttributNode *pNode = new SmAttributNode(aToken);
02347     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02348 
02349     SmNodeArray aSubNodes;
02350     aSubNodes.SetSize(2);
02351     aSubNodes.Put(0, rNodeStack.Pop());
02352     aSubNodes.Put(1, rNodeStack.Pop());
02353     pNode->SetSubNodes(aSubNodes);
02354     pNode->SetScaleMode(SCALE_WIDTH);
02355     rNodeStack.Push(pNode);
02356 
02357 }
02358 
02359 class SmXMLUnderOverContext_Impl : public SmXMLSubSupContext_Impl
02360 {
02361 public:
02362     SmXMLUnderOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02363         const OUString& rLName)
02364         : SmXMLSubSupContext_Impl(rImport,nPrefix,rLName) {}
02365     void EndElement() { GenericEndElement(TCSUB,CSUB,CSUP); }
02366 };
02367 
02368 class SmXMLMultiScriptsContext_Impl : public SmXMLSubSupContext_Impl
02369 {
02370 public:
02371     SmXMLMultiScriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02372         const OUString& rLName) :
02373         SmXMLSubSupContext_Impl(rImport,nPrefix,rLName),
02374         bHasPrescripts(FALSE) {}
02375     void EndElement();
02376     void MiddleElement();
02377     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
02378         const OUString& rLocalName,
02379         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
02380 private:
02381     sal_Bool bHasPrescripts;
02382 };
02383 
02384 class SmXMLNoneContext_Impl : public SmXMLImportContext
02385 {
02386 public:
02387     SmXMLNoneContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02388         const OUString& rLName)
02389         : SmXMLImportContext(rImport,nPrefix,rLName) {}
02390     void EndElement();
02391 };
02392 
02393 
02394 void SmXMLNoneContext_Impl::EndElement(void)
02395 {
02396     SmToken aToken;
02397     aToken.cMathChar = '\0';
02398     aToken.nGroup = 0;
02399     aToken.aText.Erase();
02400     aToken.nLevel = 5;
02401     aToken.eType = TIDENT;
02402     GetSmImport().GetNodeStack().Push(
02403         new SmTextNode(aToken,FNT_VARIABLE));
02404 }
02405 
02406 class SmXMLPrescriptsContext_Impl : public SmXMLImportContext
02407 {
02408 public:
02409     SmXMLPrescriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02410         const OUString& rLName)
02411         : SmXMLImportContext(rImport,nPrefix,rLName) {}
02412 };
02413 
02414 class SmXMLTableRowContext_Impl : public SmXMLRowContext_Impl
02415 {
02416 public:
02417     SmXMLTableRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02418         const OUString& rLName) :
02419         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
02420         {}
02421     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
02422         const OUString& rLocalName,
02423         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
02424 };
02425 
02426 
02427 class SmXMLTableContext_Impl : public SmXMLTableRowContext_Impl
02428 {
02429 public:
02430     SmXMLTableContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02431         const OUString& rLName) :
02432         SmXMLTableRowContext_Impl(rImport,nPrefix,rLName)
02433         {}
02434     void EndElement();
02435     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
02436         const OUString& rLocalName,
02437         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
02438 };
02439 
02440 
02441 class SmXMLTableCellContext_Impl : public SmXMLRowContext_Impl
02442 {
02443 public:
02444     SmXMLTableCellContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02445         const OUString& rLName) :
02446         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
02447         {}
02448 };
02449 
02450 class SmXMLAlignGroupContext_Impl : public SmXMLRowContext_Impl
02451 {
02452 public:
02453     SmXMLAlignGroupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02454         const OUString& rLName) :
02455         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
02456         {}
02457     /*Don't do anything with alignment for now*/
02458     void EndElement() {}
02459 };
02460 
02461 class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
02462 {
02463 public:
02464     SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
02465         const OUString& rLName) :
02466         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
02467         {}
02468     void EndElement();
02469 };
02470 
02471 class SmXMLOfficeContext_Impl : public SvXMLImportContext
02472 {
02473 public:
02474     SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
02475         const OUString& rLName)
02476         : SvXMLImportContext(rImport,nPrfx,rLName) {}
02477     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
02478         const OUString& rLocalName,
02479         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
02480 };
02481 
02482 SvXMLImportContext *SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
02483         const OUString& rLocalName,
02484         const uno::Reference< xml::sax::XAttributeList > &xAttrList)
02485 {
02486     SvXMLImportContext *pContext = 0;
02487     if( XML_NAMESPACE_OFFICE == nPrefix &&
02488         rLocalName == GetXMLToken(XML_META) )
02489         pContext = new SfxXMLMetaContext( GetImport(),
02490                                     XML_NAMESPACE_OFFICE, rLocalName,
02491                                     GetImport().GetModel() );
02492     else if( XML_NAMESPACE_OFFICE == nPrefix &&
02493         rLocalName == GetXMLToken(XML_SETTINGS) )
02494         pContext = new XMLDocumentSettingsContext( GetImport(),
02495                                     XML_NAMESPACE_OFFICE, rLocalName,
02496                                     xAttrList );
02497     else
02498         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
02499 
02500     return pContext;
02501 }
02502 
02503 static __FAR_DATA SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
02504 {
02505     { XML_NAMESPACE_MATH,   XML_SEMANTICS, XML_TOK_SEMANTICS },
02506     { XML_NAMESPACE_MATH,   XML_MATH,      XML_TOK_MATH   },
02507     { XML_NAMESPACE_MATH,   XML_MSTYLE,    XML_TOK_MSTYLE  },
02508     { XML_NAMESPACE_MATH,   XML_MERROR,    XML_TOK_MERROR },
02509     { XML_NAMESPACE_MATH,   XML_MPHANTOM,  XML_TOK_MPHANTOM },
02510     { XML_NAMESPACE_MATH,   XML_MROW,      XML_TOK_MROW },
02511     { XML_NAMESPACE_MATH,   XML_MFRAC,     XML_TOK_MFRAC },
02512     { XML_NAMESPACE_MATH,   XML_MSQRT,     XML_TOK_MSQRT },
02513     { XML_NAMESPACE_MATH,   XML_MROOT,     XML_TOK_MROOT },
02514     { XML_NAMESPACE_MATH,   XML_MSUB,      XML_TOK_MSUB },
02515     { XML_NAMESPACE_MATH,   XML_MSUP,      XML_TOK_MSUP },
02516     { XML_NAMESPACE_MATH,   XML_MSUBSUP,   XML_TOK_MSUBSUP },
02517     { XML_NAMESPACE_MATH,   XML_MUNDER,    XML_TOK_MUNDER },
02518     { XML_NAMESPACE_MATH,   XML_MOVER,     XML_TOK_MOVER },
02519     { XML_NAMESPACE_MATH,   XML_MUNDEROVER,    XML_TOK_MUNDEROVER },
02520     { XML_NAMESPACE_MATH,   XML_MMULTISCRIPTS, XML_TOK_MMULTISCRIPTS },
02521     { XML_NAMESPACE_MATH,   XML_MTABLE,    XML_TOK_MTABLE },
02522     { XML_NAMESPACE_MATH,   XML_MACTION,   XML_TOK_MACTION },
02523     { XML_NAMESPACE_MATH,   XML_MFENCED,   XML_TOK_MFENCED },
02524     { XML_NAMESPACE_MATH,   XML_MPADDED,   XML_TOK_MPADDED },
02525     XML_TOKEN_MAP_END
02526 };
02527 
02528 static __FAR_DATA SvXMLTokenMapEntry aPresLayoutAttrTokenMap[] =
02529 {
02530     { XML_NAMESPACE_MATH,   XML_FONTWEIGHT,      XML_TOK_FONTWEIGHT    },
02531     { XML_NAMESPACE_MATH,   XML_FONTSTYLE,       XML_TOK_FONTSTYLE     },
02532     { XML_NAMESPACE_MATH,   XML_FONTSIZE,        XML_TOK_FONTSIZE      },
02533     { XML_NAMESPACE_MATH,   XML_FONTFAMILY,      XML_TOK_FONTFAMILY    },
02534     { XML_NAMESPACE_MATH,   XML_COLOR,           XML_TOK_COLOR },
02535     XML_TOKEN_MAP_END
02536 };
02537 
02538 static __FAR_DATA SvXMLTokenMapEntry aFencedAttrTokenMap[] =
02539 {
02540     { XML_NAMESPACE_MATH,   XML_OPEN,       XML_TOK_OPEN },
02541     { XML_NAMESPACE_MATH,   XML_CLOSE,      XML_TOK_CLOSE },
02542     XML_TOKEN_MAP_END
02543 };
02544 
02545 static __FAR_DATA SvXMLTokenMapEntry aOperatorAttrTokenMap[] =
02546 {
02547     { XML_NAMESPACE_MATH,   XML_STRETCHY,      XML_TOK_STRETCHY },
02548     XML_TOKEN_MAP_END
02549 };
02550 
02551 static __FAR_DATA SvXMLTokenMapEntry aAnnotationAttrTokenMap[] =
02552 {
02553     { XML_NAMESPACE_MATH,   XML_ENCODING,      XML_TOK_ENCODING },
02554     XML_TOKEN_MAP_END
02555 };
02556 
02557 
02558 static __FAR_DATA SvXMLTokenMapEntry aPresElemTokenMap[] =
02559 {
02560     { XML_NAMESPACE_MATH,   XML_ANNOTATION,    XML_TOK_ANNOTATION },
02561     { XML_NAMESPACE_MATH,   XML_MI,    XML_TOK_MI },
02562     { XML_NAMESPACE_MATH,   XML_MN,    XML_TOK_MN },
02563     { XML_NAMESPACE_MATH,   XML_MO,    XML_TOK_MO },
02564     { XML_NAMESPACE_MATH,   XML_MTEXT, XML_TOK_MTEXT },
02565     { XML_NAMESPACE_MATH,   XML_MSPACE,XML_TOK_MSPACE },
02566     { XML_NAMESPACE_MATH,   XML_MS,    XML_TOK_MS },
02567     { XML_NAMESPACE_MATH,   XML_MALIGNGROUP,   XML_TOK_MALIGNGROUP },
02568     XML_TOKEN_MAP_END
02569 };
02570 
02571 static __FAR_DATA SvXMLTokenMapEntry aPresScriptEmptyElemTokenMap[] =
02572 {
02573     { XML_NAMESPACE_MATH,   XML_MPRESCRIPTS,   XML_TOK_MPRESCRIPTS },
02574     { XML_NAMESPACE_MATH,   XML_NONE,  XML_TOK_NONE },
02575     XML_TOKEN_MAP_END
02576 };
02577 
02578 static __FAR_DATA SvXMLTokenMapEntry aPresTableElemTokenMap[] =
02579 {
02580     { XML_NAMESPACE_MATH,   XML_MTR,       XML_TOK_MTR },
02581     { XML_NAMESPACE_MATH,   XML_MTD,       XML_TOK_MTD },
02582     XML_TOKEN_MAP_END
02583 };
02584 
02585 static __FAR_DATA SvXMLTokenMapEntry aColorTokenMap[] =
02586 {
02587     { XML_NAMESPACE_MATH,   XML_BLACK,        TBLACK},
02588     { XML_NAMESPACE_MATH,   XML_WHITE,        TWHITE},
02589     { XML_NAMESPACE_MATH,   XML_RED,          TRED},
02590     { XML_NAMESPACE_MATH,   XML_GREEN,        TGREEN},
02591     { XML_NAMESPACE_MATH,   XML_BLUE,         TBLUE},
02592     { XML_NAMESPACE_MATH,   XML_AQUA,         TCYAN},
02593     { XML_NAMESPACE_MATH,   XML_FUCHSIA,      TMAGENTA},
02594     { XML_NAMESPACE_MATH,   XML_YELLOW,       TYELLOW},
02595     XML_TOKEN_MAP_END
02596 };
02597 
02598 
02599 const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
02600 {
02601     if(!pPresLayoutElemTokenMap)
02602         pPresLayoutElemTokenMap = new SvXMLTokenMap(aPresLayoutElemTokenMap);
02603     return *pPresLayoutElemTokenMap;
02604 }
02605 
02606 const SvXMLTokenMap& SmXMLImport::GetPresLayoutAttrTokenMap()
02607 {
02608     if(!pPresLayoutAttrTokenMap)
02609         pPresLayoutAttrTokenMap = new SvXMLTokenMap(aPresLayoutAttrTokenMap);
02610     return *pPresLayoutAttrTokenMap;
02611 }
02612 
02613 
02614 const SvXMLTokenMap& SmXMLImport::GetFencedAttrTokenMap()
02615 {
02616     if(!pFencedAttrTokenMap)
02617         pFencedAttrTokenMap = new SvXMLTokenMap(aFencedAttrTokenMap);
02618     return *pFencedAttrTokenMap;
02619 }
02620 
02621 const SvXMLTokenMap& SmXMLImport::GetOperatorAttrTokenMap()
02622 {
02623     if(!pOperatorAttrTokenMap)
02624         pOperatorAttrTokenMap = new SvXMLTokenMap(aOperatorAttrTokenMap);
02625     return *pOperatorAttrTokenMap;
02626 }
02627 
02628 const SvXMLTokenMap& SmXMLImport::GetAnnotationAttrTokenMap()
02629 {
02630     if(!pAnnotationAttrTokenMap)
02631         pAnnotationAttrTokenMap = new SvXMLTokenMap(aAnnotationAttrTokenMap);
02632     return *pAnnotationAttrTokenMap;
02633 }
02634 
02635 const SvXMLTokenMap& SmXMLImport::GetPresElemTokenMap()
02636 {
02637     if(!pPresElemTokenMap)
02638         pPresElemTokenMap = new SvXMLTokenMap(aPresElemTokenMap);
02639     return *pPresElemTokenMap;
02640 }
02641 
02642 const SvXMLTokenMap& SmXMLImport::GetPresScriptEmptyElemTokenMap()
02643 {
02644     if(!pPresScriptEmptyElemTokenMap)
02645         pPresScriptEmptyElemTokenMap = new
02646             SvXMLTokenMap(aPresScriptEmptyElemTokenMap);
02647     return *pPresScriptEmptyElemTokenMap;
02648 }
02649 
02650 const SvXMLTokenMap& SmXMLImport::GetPresTableElemTokenMap()
02651 {
02652     if(!pPresTableElemTokenMap)
02653         pPresTableElemTokenMap = new SvXMLTokenMap(aPresTableElemTokenMap);
02654     return *pPresTableElemTokenMap;
02655 }
02656 
02657 const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
02658 {
02659     if(!pColorTokenMap)
02660         pColorTokenMap = new SvXMLTokenMap(aColorTokenMap);
02661     return *pColorTokenMap;
02662 }
02663 
02664 SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
02665     sal_uInt16 nPrefix,
02666     const OUString& rLocalName,
02667     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
02668 {
02669     SvXMLImportContext* pContext = 0L;
02670 
02671     const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresLayoutElemTokenMap();
02672 
02673     //UINT32 nTest = rTokenMap.Get(nPrefix, rLocalName);
02674 
02675     switch(rTokenMap.Get(nPrefix, rLocalName))
02676     {
02677         //Consider semantics a dummy except for any starmath annotations
02678         case XML_TOK_SEMANTICS:
02679             pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
02680                 xAttrList);
02681             break;
02682         /*General Layout Schemata*/
02683         case XML_TOK_MROW:
02684             pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
02685                 xAttrList);
02686             break;
02687         case XML_TOK_MFRAC:
02688             pContext = GetSmImport().CreateFracContext(nPrefix,rLocalName,
02689                 xAttrList);
02690             break;
02691         case XML_TOK_MSQRT:
02692             pContext = GetSmImport().CreateSqrtContext(nPrefix,rLocalName,
02693                 xAttrList);
02694             break;
02695         case XML_TOK_MROOT:
02696             pContext = GetSmImport().CreateRootContext(nPrefix,rLocalName,
02697                 xAttrList);
02698             break;
02699         case XML_TOK_MSTYLE:
02700             pContext = GetSmImport().CreateStyleContext(nPrefix,rLocalName,
02701                 xAttrList);
02702             break;
02703         case XML_TOK_MERROR:
02704             pContext = GetSmImport().CreateErrorContext(nPrefix,rLocalName,
02705                 xAttrList);
02706             break;
02707         case XML_TOK_MPADDED:
02708             pContext = GetSmImport().CreatePaddedContext(nPrefix,rLocalName,
02709                 xAttrList);
02710             break;
02711         case XML_TOK_MPHANTOM:
02712             pContext = GetSmImport().CreatePhantomContext(nPrefix,rLocalName,
02713                 xAttrList);
02714             break;
02715         case XML_TOK_MFENCED:
02716             pContext = GetSmImport().CreateFencedContext(nPrefix,rLocalName,
02717                 xAttrList);
02718             break;
02719         /*Script and Limit Schemata*/
02720         case XML_TOK_MSUB:
02721             pContext = GetSmImport().CreateSubContext(nPrefix,rLocalName,
02722                 xAttrList);
02723             break;
02724         case XML_TOK_MSUP:
02725             pContext = GetSmImport().CreateSupContext(nPrefix,rLocalName,
02726                 xAttrList);
02727             break;
02728         case XML_TOK_MSUBSUP:
02729             pContext = GetSmImport().CreateSubSupContext(nPrefix,rLocalName,
02730                 xAttrList);
02731             break;
02732         case XML_TOK_MUNDER:
02733             pContext = GetSmImport().CreateUnderContext(nPrefix,rLocalName,
02734                 xAttrList);
02735             break;
02736         case XML_TOK_MOVER:
02737             pContext = GetSmImport().CreateOverContext(nPrefix,rLocalName,
02738                 xAttrList);
02739             break;
02740         case XML_TOK_MUNDEROVER:
02741             pContext = GetSmImport().CreateUnderOverContext(nPrefix,rLocalName,
02742                 xAttrList);
02743             break;
02744         case XML_TOK_MMULTISCRIPTS:
02745             pContext = GetSmImport().CreateMultiScriptsContext(nPrefix,
02746                 rLocalName, xAttrList);
02747             break;
02748         case XML_TOK_MTABLE:
02749             pContext = GetSmImport().CreateTableContext(nPrefix,
02750                 rLocalName, xAttrList);
02751             break;
02752         case XML_TOK_MACTION:
02753             pContext = GetSmImport().CreateActionContext(nPrefix,
02754                 rLocalName, xAttrList);
02755             break;
02756         default:
02757             /*Basically theres an implicit mrow around certain bare
02758              *elements, use a RowContext to see if this is one of
02759              *those ones*/
02760             SmXMLRowContext_Impl aTempContext(GetSmImport(),nPrefix,
02761                 GetXMLToken(XML_MROW));
02762 
02763             pContext = aTempContext.StrictCreateChildContext(nPrefix,
02764                 rLocalName, xAttrList);
02765             break;
02766     }
02767     return pContext;
02768 }
02769 
02770 void SmXMLDocContext_Impl::EndElement()
02771 {
02772     SmNodeArray ContextArray;
02773     ContextArray.SetSize(1);
02774     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02775 
02776     for(ULONG i=0;i< 1;i++)
02777         ContextArray.Put(i, rNodeStack.Pop());
02778 
02779     SmToken aDummy;
02780     SmStructureNode *pSNode = new SmLineNode(aDummy);
02781     pSNode->SetSubNodes(ContextArray);
02782     rNodeStack.Push(pSNode);
02783 
02784     SmNodeArray  LineArray;
02785     ULONG n = rNodeStack.Count();
02786     LineArray.SetSize(n);
02787     for (ULONG j = 0; j < n; j++)
02788         LineArray.Put(n - (j + 1), rNodeStack.Pop());
02789     SmStructureNode *pSNode2 = new SmTableNode(aDummy);
02790     pSNode2->SetSubNodes(LineArray);
02791     rNodeStack.Push(pSNode2);
02792 }
02793 
02794 void SmXMLFracContext_Impl::EndElement()
02795 {
02796     SmToken aToken;
02797     aToken.cMathChar = '\0';
02798     aToken.nGroup = 0;
02799     aToken.nLevel = 0;
02800     aToken.eType = TOVER;
02801     SmStructureNode *pSNode = new SmBinVerNode(aToken);
02802     SmNode *pOper = new SmRectangleNode(aToken);
02803     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02804     DBG_ASSERT(rNodeStack.Count() - nElementCount == 2,
02805         "Fraction (mfrac) tag is missing component");
02806 
02807     if (rNodeStack.Count() - nElementCount == 2)
02808     {
02809         SmNode *pSecond = rNodeStack.Pop();
02810         SmNode *pFirst = rNodeStack.Pop();
02811         pSNode->SetSubNodes(pFirst,pOper,pSecond);
02812         rNodeStack.Push(pSNode);
02813     }
02814 }
02815 
02816 void SmXMLRootContext_Impl::EndElement()
02817 {
02818     /*The <mroot> element requires exactly 2 arguments.*/
02819     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount == 2,
02820         "Root tag is missing component");
02821 
02822     SmToken aToken;
02823     aToken.cMathChar = MS_SQRT;  //Temporary: alert, based on StarSymbol font
02824     aToken.nGroup = 0;
02825     aToken.nLevel = 0;
02826     aToken.eType = TNROOT;
02827     SmStructureNode *pSNode = new SmRootNode(aToken);
02828     SmNode *pOper = new SmRootSymbolNode(aToken);
02829     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02830     SmNode *pIndex = rNodeStack.Pop();
02831     SmNode *pBase = rNodeStack.Pop();
02832     pSNode->SetSubNodes(pIndex,pOper,pBase);
02833     rNodeStack.Push(pSNode);
02834 }
02835 
02836 void SmXMLSqrtContext_Impl::EndElement()
02837 {
02838     /*
02839     <msqrt> accepts any number of arguments; if this number is not 1, its
02840     contents are treated as a single "inferred <mrow>" containing its
02841     arguments
02842     */
02843     if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
02844         SmXMLRowContext_Impl::EndElement();
02845 
02846     SmToken aToken;
02847     aToken.cMathChar = MS_SQRT;  //Temporary: alert, based on StarSymbol font
02848     aToken.nGroup = 0;
02849     aToken.nLevel = 0;
02850     aToken.eType = TSQRT;
02851     SmStructureNode *pSNode = new SmRootNode(aToken);
02852     SmNode *pOper = new SmRootSymbolNode(aToken);
02853     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02854     pSNode->SetSubNodes(0,pOper,rNodeStack.Pop());
02855     rNodeStack.Push(pSNode);
02856 }
02857 
02858 void SmXMLRowContext_Impl::EndElement()
02859 {
02860     SmNodeArray aRelationArray;
02861     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
02862     ULONG nSize = rNodeStack.Count()-nElementCount;
02863 
02864     if (nSize)
02865     {
02866         aRelationArray.SetSize(nSize);
02867         for(ULONG j=rNodeStack.Count()-nElementCount;j > 0;j--)
02868             aRelationArray.Put(j-1,rNodeStack.Pop());
02869 
02870 
02871         //If the first or last element is an operator with stretchyness
02872         //set then we must create a brace node here from those elements,
02873         //removing the stretchness from the operators and applying it to
02874         //ourselves, and creating the appropiate dummy StarMath none bracket
02875         //to balance the arrangement
02876         if (((aRelationArray.Get(0)->GetScaleMode() == SCALE_HEIGHT)
02877             && (aRelationArray.Get(0)->GetType() == NMATH))
02878         || ((aRelationArray.Get(nSize-1)->GetScaleMode() == SCALE_HEIGHT)
02879             && (aRelationArray.Get(nSize-1)->GetType() == NMATH)))
02880         {
02881             SmToken aToken;
02882             aToken.cMathChar = '\0';
02883             aToken.nGroup = 0;
02884             aToken.nLevel = 5;
02885 
02886             int nLeft=0,nRight=0;
02887             if ((aRelationArray.Get(0)->GetScaleMode() == SCALE_HEIGHT)
02888                 && (aRelationArray.Get(0)->GetType() == NMATH))
02889             {
02890                 aToken = aRelationArray.Get(0)->GetToken();
02891                 nLeft=1;
02892             }
02893             else
02894                 aToken.cMathChar = '\0';
02895 
02896             aToken.eType = TLPARENT;
02897             SmNode *pLeft = new SmMathSymbolNode(aToken);
02898 
02899             if ((aRelationArray.Get(nSize-1)->GetScaleMode() == SCALE_HEIGHT)
02900                 && (aRelationArray.Get(nSize-1)->GetType() == NMATH))
02901             {
02902                 aToken = aRelationArray.Get(nSize-1)->GetToken();
02903                 nRight=1;
02904             }
02905             else
02906                 aToken.cMathChar = '\0';
02907 
02908             aToken.eType = TRPARENT;
02909             SmNode *pRight = new SmMathSymbolNode(aToken);
02910 
02911             SmNodeArray aRelationArray2;
02912 
02914             int nRelArrSize = nSize-nLeft-nRight;
02915             if (nRelArrSize > 0)
02916             {
02917                 aRelationArray2.SetSize(nRelArrSize);
02918                 for(int i=0;i < nRelArrSize;i++)
02919                     aRelationArray2.Put(i,aRelationArray.Get(i+nLeft));
02920             }
02921 
02922             SmToken aDummy;
02923             SmStructureNode *pSNode = new SmBraceNode(aToken);
02924             SmStructureNode *pBody = new SmExpressionNode(aDummy);
02925             pBody->SetSubNodes(aRelationArray2);
02926 
02927             pSNode->SetSubNodes(pLeft,pBody,pRight);
02928             pSNode->SetScaleMode(SCALE_HEIGHT);
02929             rNodeStack.Push(pSNode);
02930             return;
02931         }
02932     }
02933     else //Multiple newlines result in empty row elements
02934     {
02935         aRelationArray.SetSize(1);
02936         SmToken aToken;
02937         aToken.cMathChar = '\0';
02938         aToken.nGroup = 0;
02939         aToken.nLevel = 5;
02940         aToken.eType = TNEWLINE;
02941         aRelationArray.Put(0,new SmLineNode(aToken));
02942     }
02943 
02944     SmToken aDummy;
02945     SmStructureNode *pSNode = new SmExpressionNode(aDummy);
02946     pSNode->SetSubNodes(aRelationArray);
02947     rNodeStack.Push(pSNode);
02948 }
02949 
02950 
02951 
02952 
02953 
02954 SvXMLImportContext *SmXMLRowContext_Impl::StrictCreateChildContext(
02955     sal_uInt16 nPrefix,
02956     const OUString& rLocalName,
02957     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
02958 {
02959     SvXMLImportContext* pContext = 0L;
02960 
02961     const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresElemTokenMap();
02962     switch(rTokenMap.Get(nPrefix, rLocalName))
02963     {
02964         /*Note that these should accept malignmark subelements, but do not*/
02965         case XML_TOK_MN:
02966             pContext = GetSmImport().CreateNumberContext(nPrefix,rLocalName,
02967                 xAttrList);
02968             break;
02969         case XML_TOK_MI:
02970             pContext = GetSmImport().CreateIdentifierContext(nPrefix,rLocalName,
02971                 xAttrList);
02972             break;
02973         case XML_TOK_MO:
02974             pContext = GetSmImport().CreateOperatorContext(nPrefix,rLocalName,
02975                 xAttrList);
02976             break;
02977         case XML_TOK_MTEXT:
02978             pContext = GetSmImport().CreateTextContext(nPrefix,rLocalName,
02979                 xAttrList);
02980             break;
02981         case XML_TOK_MSPACE:
02982             pContext = GetSmImport().CreateSpaceContext(nPrefix,rLocalName,
02983                 xAttrList);
02984             break;
02985         case XML_TOK_MS:
02986             pContext = GetSmImport().CreateStringContext(nPrefix,rLocalName,
02987                 xAttrList);
02988             break;
02989 
02990         /*Note: The maligngroup should only be seen when the row
02991          * (or decendants) are in a table*/
02992         case XML_TOK_MALIGNGROUP:
02993             pContext = GetSmImport().CreateAlignGroupContext(nPrefix,rLocalName,
02994                 xAttrList);
02995             break;
02996 
02997         case XML_TOK_ANNOTATION:
02998             pContext = GetSmImport().CreateAnnotationContext(nPrefix,rLocalName,
02999                 xAttrList);
03000             break;
03001 
03002         default:
03003             break;
03004     }
03005     return pContext;
03006 }
03007 
03008 
03009 
03010 SvXMLImportContext *SmXMLRowContext_Impl::CreateChildContext(
03011     sal_uInt16 nPrefix,
03012     const OUString& rLocalName,
03013     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
03014 {
03015     SvXMLImportContext* pContext = StrictCreateChildContext(nPrefix,
03016     rLocalName, xAttrList);
03017 
03018     if (!pContext)
03019     {
03020         //Hmm, unrecognized for this level, check to see if its
03021         //an element that can have an implicit schema around it
03022         pContext = SmXMLDocContext_Impl::CreateChildContext(nPrefix,
03023             rLocalName,xAttrList);
03024     }
03025     return pContext;
03026 }
03027 
03028 
03029 SvXMLImportContext *SmXMLMultiScriptsContext_Impl::CreateChildContext(
03030     sal_uInt16 nPrefix,
03031     const OUString& rLocalName,
03032     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
03033 {
03034     SvXMLImportContext* pContext = 0L;
03035 
03036     const SvXMLTokenMap& rTokenMap = GetSmImport().
03037         GetPresScriptEmptyElemTokenMap();
03038     switch(rTokenMap.Get(nPrefix, rLocalName))
03039     {
03040         case XML_TOK_MPRESCRIPTS:
03041             MiddleElement();
03042             pContext = GetSmImport().CreatePrescriptsContext(nPrefix,
03043                 rLocalName, xAttrList);
03044             break;
03045         case XML_TOK_NONE:
03046             pContext = GetSmImport().CreateNoneContext(nPrefix,rLocalName,
03047                 xAttrList);
03048             break;
03049         default:
03050             pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
03051                 rLocalName,xAttrList);
03052             break;
03053     }
03054     return pContext;
03055 }
03056 
03057 void SmXMLMultiScriptsContext_Impl::MiddleElement()
03058 {
03059     bHasPrescripts=sal_True;
03060 
03061     DBG_ASSERT(GetSmImport().GetNodeStack().Count() - nElementCount > 0,
03062         "Sub has no arguments");
03063     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
03064     if (rNodeStack.Count()-nElementCount > 1)
03065     {
03066         SmToken aToken;
03067         aToken.cMathChar = '\0';
03068         aToken.nGroup = 0;
03069         aToken.nLevel = 0;
03070         aToken.eType = TRSUB;
03071         ULONG nFinalCount = rNodeStack.Count()-nElementCount-1;
03072 
03073         SmNodeStack aReverseStack;
03074         while (rNodeStack.Count()-nElementCount)
03075         {
03076             SmNode *pThing = rNodeStack.Pop();
03077             aReverseStack.Push(pThing);
03078         }
03079 
03080         for (ULONG nCount=0;nCount < nFinalCount;nCount+=2)
03081         {
03082             SmSubSupNode *pNode = new SmSubSupNode(aToken);
03083 
03084             // initialize subnodes array
03085             SmNodeArray  aSubNodes;
03086             aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
03087             for (ULONG i = 1;  i < aSubNodes.GetSize();  i++)
03088                 aSubNodes.Put(i, NULL);
03089 
03090             /*On each loop the base and its sub sup pair becomes the
03091              base for the next loop to which the next sub sup pair is
03092              attached, i.e. wheels within wheels*/
03093             //if (nCount == 0)
03094             aSubNodes.Put(0, aReverseStack.Pop());
03095 
03096             SmNode *pScriptNode = aReverseStack.Pop();
03097 
03098             if ((pScriptNode->GetToken().eType != TIDENT) ||
03099                 (pScriptNode->GetToken().aText.Len()))
03100                 aSubNodes.Put(RSUB+1,pScriptNode);
03101             pScriptNode = aReverseStack.Pop();
03102             if ((pScriptNode->GetToken().eType != TIDENT) ||
03103                 (pScriptNode->GetToken().aText.Len()))
03104                 aSubNodes.Put(RSUP+1,pScriptNode);
03105 
03106             pNode->SetSubNodes(aSubNodes);
03107             aReverseStack.Push(pNode);
03108         }
03109     rNodeStack.Push(aReverseStack.Pop());
03110     }
03111 }
03112 
03113 
03114 void SmXMLTableContext_Impl::EndElement()
03115 {
03116     SmNodeArray aExpressionArray;
03117     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
03118     SmNodeStack aReverseStack;
03119     aExpressionArray.SetSize(rNodeStack.Count()-nElementCount);
03120 
03121     ULONG nRows = rNodeStack.Count()-nElementCount;
03122     USHORT nCols = 0;
03123 
03124     SmStructureNode *pArray;
03125     for(ULONG i=rNodeStack.Count()-nElementCount;i > 0;i--)
03126     {
03127         pArray = (SmStructureNode *)rNodeStack.Pop();
03128         if (pArray->GetNumSubNodes() == 0)
03129         {
03130             //This is a little tricky, it is possible that there was
03131             //be elements that were not inside a <mtd> pair, in which
03132             //case they will not be in a row, i.e. they will not have
03133             //SubNodes, so we have to wait until here before we can
03134             //resolve the situation. Implicitsurrounding tags are
03135             //surprisingly difficult to get right within this
03136             //architecture
03137 
03138             SmNodeArray aRelationArray;
03139             aRelationArray.SetSize(1);
03140             aRelationArray.Put(0,pArray);
03141             SmToken aDummy;
03142             pArray = new SmExpressionNode(aDummy);
03143             pArray->SetSubNodes(aRelationArray);
03144         }
03145 
03146         if (pArray->GetNumSubNodes() > nCols)
03147             nCols = pArray->GetNumSubNodes();
03148         aReverseStack.Push(pArray);
03149     }
03150     aExpressionArray.SetSize(nCols*nRows);
03151     ULONG j=0;
03152     while (aReverseStack.Count())
03153     {
03154         pArray = (SmStructureNode *)aReverseStack.Pop();
03155         for (USHORT i=0;i<pArray->GetNumSubNodes();i++)
03156             aExpressionArray.Put(j++,pArray->GetSubNode(i));
03157     }
03158 
03159     SmToken aToken;
03160     aToken.cMathChar = '\0';
03161     aToken.nGroup = TRGROUP;
03162     aToken.nLevel = 0;
03163     aToken.eType = TMATRIX;
03164     SmMatrixNode *pSNode = new SmMatrixNode(aToken);
03165     pSNode->SetSubNodes(aExpressionArray);
03166     pSNode->SetRowCol(static_cast<USHORT>(nRows),nCols);
03167     rNodeStack.Push(pSNode);
03168 }
03169 
03170 SvXMLImportContext *SmXMLTableRowContext_Impl::CreateChildContext(
03171     sal_uInt16 nPrefix,
03172     const OUString& rLocalName,
03173     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
03174 {
03175     SvXMLImportContext* pContext = 0L;
03176 
03177     const SvXMLTokenMap& rTokenMap = GetSmImport().
03178         GetPresTableElemTokenMap();
03179     switch(rTokenMap.Get(nPrefix, rLocalName))
03180     {
03181         case XML_TOK_MTD:
03182             pContext = GetSmImport().CreateTableCellContext(nPrefix,
03183                 rLocalName, xAttrList);
03184             break;
03185         default:
03186             pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
03187                 rLocalName,xAttrList);
03188             break;
03189     }
03190     return pContext;
03191 }
03192 
03193 SvXMLImportContext *SmXMLTableContext_Impl::CreateChildContext(
03194     sal_uInt16 nPrefix,
03195     const OUString& rLocalName,
03196     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
03197 {
03198     SvXMLImportContext* pContext = 0L;
03199 
03200     const SvXMLTokenMap& rTokenMap = GetSmImport().
03201         GetPresTableElemTokenMap();
03202     switch(rTokenMap.Get(nPrefix, rLocalName))
03203     {
03204         case XML_TOK_MTR:
03205             pContext = GetSmImport().CreateTableRowContext(nPrefix,rLocalName,
03206                 xAttrList);
03207             break;
03208         default:
03209             pContext = SmXMLTableRowContext_Impl::CreateChildContext(nPrefix,
03210                 rLocalName,xAttrList);
03211             break;
03212     }
03213     return pContext;
03214 }
03215 
03216 void SmXMLMultiScriptsContext_Impl::EndElement()
03217 {
03218     if (!bHasPrescripts)
03219         MiddleElement();
03220 
03221     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
03222     if (rNodeStack.Count()-nElementCount > 1)
03223     {
03224         SmToken aToken;
03225         aToken.cMathChar = '\0';
03226         aToken.nGroup = 0;
03227         aToken.nLevel = 0;
03228         aToken.eType = TLSUB;
03229         ULONG nFinalCount = rNodeStack.Count()-nElementCount-1;
03230 
03231         SmNodeStack aReverseStack;
03232         while (rNodeStack.Count()-nElementCount)
03233             aReverseStack.Push(rNodeStack.Pop());
03234         for (ULONG nCount=0;nCount < nFinalCount;nCount+=2)
03235         {
03236             SmSubSupNode *pNode = new SmSubSupNode(aToken);
03237 
03238             // initialize subnodes array
03239             SmNodeArray  aSubNodes;
03240             aSubNodes.SetSize(1 + SUBSUP_NUM_ENTRIES);
03241             for (ULONG i = 1;  i < aSubNodes.GetSize();  i++)
03242                 aSubNodes.Put(i, NULL);
03243 
03244             /*On each loop the base and its sub sup pair becomes the
03245              base for the next loop to which the next sub sup pair is
03246              attached, i.e. wheels within wheels*/
03247             //if (nCount == 0)
03248             aSubNodes.Put(0, aReverseStack.Pop());
03249 
03250             SmNode *pScriptNode = aReverseStack.Pop();
03251             if (pScriptNode->GetToken().aText.Len())
03252                 aSubNodes.Put(LSUB+1,pScriptNode);
03253             pScriptNode = aReverseStack.Pop();
03254             if (pScriptNode->GetToken().aText.Len())
03255                 aSubNodes.Put(LSUP+1,pScriptNode);
03256 
03257             pNode->SetSubNodes(aSubNodes);
03258             aReverseStack.Push(pNode);
03259         }
03260     rNodeStack.Push(aReverseStack.Pop());
03261     }
03262 
03263 }
03264 void SmXMLActionContext_Impl::EndElement()
03265 {
03266     /*For now we will just assume that the
03267      selected attribute is one, and then just display
03268      that expression alone, i.e. remove all expect the
03269      first pushed one*/
03270 
03271     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
03272     for(ULONG i=rNodeStack.Count()-nElementCount;i > 1;i--)
03273     {
03274         delete rNodeStack.Pop();
03275     }
03276 }
03277 
03278 SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
03279     const OUString &rLocalName,
03280     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03281 {
03282     if( XML_NAMESPACE_OFFICE == nPrefix )
03283         return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
03284     else
03285         return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
03286 }
03287 
03288 SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
03289     const OUString &rLocalName,
03290     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03291 {
03292         return new SmXMLRowContext_Impl(*this,nPrefix,rLocalName);
03293 }
03294 
03295 SvXMLImportContext *SmXMLImport::CreateTextContext(sal_uInt16 nPrefix,
03296     const OUString &rLocalName,
03297     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03298 {
03299         return new SmXMLTextContext_Impl(*this,nPrefix,rLocalName);
03300 }
03301 
03302 SvXMLImportContext *SmXMLImport::CreateAnnotationContext(sal_uInt16 nPrefix,
03303     const OUString &rLocalName,
03304     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03305 {
03306         return new SmXMLAnnotationContext_Impl(*this,nPrefix,rLocalName);
03307 }
03308 
03309 SvXMLImportContext *SmXMLImport::CreateStringContext(sal_uInt16 nPrefix,
03310     const OUString &rLocalName,
03311     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03312 {
03313         return new SmXMLStringContext_Impl(*this,nPrefix,rLocalName);
03314 }
03315 
03316 SvXMLImportContext *SmXMLImport::CreateNumberContext(sal_uInt16 nPrefix,
03317     const OUString &rLocalName,
03318     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03319 {
03320         return new SmXMLNumberContext_Impl(*this,nPrefix,rLocalName);
03321 }
03322 
03323 SvXMLImportContext *SmXMLImport::CreateIdentifierContext(sal_uInt16 nPrefix,
03324     const OUString &rLocalName,
03325     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03326 {
03327         return new SmXMLIdentifierContext_Impl(*this,nPrefix,rLocalName);
03328 }
03329 
03330 SvXMLImportContext *SmXMLImport::CreateOperatorContext(sal_uInt16 nPrefix,
03331     const OUString &rLocalName,
03332     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03333 {
03334     return new SmXMLOperatorContext_Impl(*this,nPrefix,rLocalName);
03335 }
03336 
03337 SvXMLImportContext *SmXMLImport::CreateSpaceContext(sal_uInt16 nPrefix,
03338     const OUString &rLocalName,
03339     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03340 {
03341     return new SmXMLSpaceContext_Impl(*this,nPrefix,rLocalName);
03342 }
03343 
03344 
03345 SvXMLImportContext *SmXMLImport::CreateFracContext(sal_uInt16 nPrefix,
03346     const OUString &rLocalName,
03347     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03348 {
03349         return new SmXMLFracContext_Impl(*this,nPrefix,rLocalName);
03350 }
03351 
03352 SvXMLImportContext *SmXMLImport::CreateSqrtContext(sal_uInt16 nPrefix,
03353     const OUString &rLocalName,
03354     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03355 {
03356         return new SmXMLSqrtContext_Impl(*this,nPrefix,rLocalName);
03357 }
03358 
03359 SvXMLImportContext *SmXMLImport::CreateRootContext(sal_uInt16 nPrefix,
03360     const OUString &rLocalName,
03361     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03362 {
03363         return new SmXMLRootContext_Impl(*this,nPrefix,rLocalName);
03364 }
03365 
03366 SvXMLImportContext *SmXMLImport::CreateStyleContext(sal_uInt16 nPrefix,
03367     const OUString &rLocalName,
03368     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03369 {
03370         return new SmXMLStyleContext_Impl(*this,nPrefix,rLocalName);
03371 }
03372 
03373 SvXMLImportContext *SmXMLImport::CreatePaddedContext(sal_uInt16 nPrefix,
03374     const OUString &rLocalName,
03375     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03376 {
03377         return new SmXMLPaddedContext_Impl(*this,nPrefix,rLocalName);
03378 }
03379 
03380 SvXMLImportContext *SmXMLImport::CreatePhantomContext(sal_uInt16 nPrefix,
03381     const OUString &rLocalName,
03382     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03383 {
03384         return new SmXMLPhantomContext_Impl(*this,nPrefix,rLocalName);
03385 }
03386 
03387 SvXMLImportContext *SmXMLImport::CreateFencedContext(sal_uInt16 nPrefix,
03388     const OUString &rLocalName,
03389     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03390 {
03391         return new SmXMLFencedContext_Impl(*this,nPrefix,rLocalName);
03392 }
03393 
03394 SvXMLImportContext *SmXMLImport::CreateErrorContext(sal_uInt16 nPrefix,
03395     const OUString &rLocalName,
03396     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03397 {
03398         return new SmXMLErrorContext_Impl(*this,nPrefix,rLocalName);
03399 }
03400 
03401 SvXMLImportContext *SmXMLImport::CreateSubContext(sal_uInt16 nPrefix,
03402     const OUString &rLocalName,
03403     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03404 {
03405         return new SmXMLSubContext_Impl(*this,nPrefix,rLocalName);
03406 }
03407 
03408 SvXMLImportContext *SmXMLImport::CreateSubSupContext(sal_uInt16 nPrefix,
03409     const OUString &rLocalName,
03410     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03411 {
03412         return new SmXMLSubSupContext_Impl(*this,nPrefix,rLocalName);
03413 }
03414 
03415 SvXMLImportContext *SmXMLImport::CreateSupContext(sal_uInt16 nPrefix,
03416     const OUString &rLocalName,
03417     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03418 {
03419         return new SmXMLSupContext_Impl(*this,nPrefix,rLocalName);
03420 }
03421 
03422 SvXMLImportContext *SmXMLImport::CreateUnderContext(sal_uInt16 nPrefix,
03423     const OUString &rLocalName,
03424     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03425 {
03426         return new SmXMLUnderContext_Impl(*this,nPrefix,rLocalName);
03427 }
03428 
03429 SvXMLImportContext *SmXMLImport::CreateOverContext(sal_uInt16 nPrefix,
03430     const OUString &rLocalName,
03431     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03432 {
03433         return new SmXMLOverContext_Impl(*this,nPrefix,rLocalName);
03434 }
03435 
03436 SvXMLImportContext *SmXMLImport::CreateUnderOverContext(sal_uInt16 nPrefix,
03437     const OUString &rLocalName,
03438     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03439 {
03440         return new SmXMLUnderOverContext_Impl(*this,nPrefix,rLocalName);
03441 }
03442 
03443 SvXMLImportContext *SmXMLImport::CreateMultiScriptsContext(sal_uInt16 nPrefix,
03444     const OUString &rLocalName,
03445     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03446 {
03447         return new SmXMLMultiScriptsContext_Impl(*this,nPrefix,rLocalName);
03448 }
03449 
03450 SvXMLImportContext *SmXMLImport::CreateTableContext(sal_uInt16 nPrefix,
03451     const OUString &rLocalName,
03452     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03453 {
03454         return new SmXMLTableContext_Impl(*this,nPrefix,rLocalName);
03455 }
03456 SvXMLImportContext *SmXMLImport::CreateTableRowContext(sal_uInt16 nPrefix,
03457     const OUString &rLocalName,
03458     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03459 {
03460         return new SmXMLTableRowContext_Impl(*this,nPrefix,rLocalName);
03461 }
03462 SvXMLImportContext *SmXMLImport::CreateTableCellContext(sal_uInt16 nPrefix,
03463     const OUString &rLocalName,
03464     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03465 {
03466         return new SmXMLTableCellContext_Impl(*this,nPrefix,rLocalName);
03467 }
03468 
03469 SvXMLImportContext *SmXMLImport::CreateNoneContext(sal_uInt16 nPrefix,
03470     const OUString &rLocalName,
03471     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03472 {
03473         return new SmXMLNoneContext_Impl(*this,nPrefix,rLocalName);
03474 }
03475 
03476 SvXMLImportContext *SmXMLImport::CreatePrescriptsContext(sal_uInt16 nPrefix,
03477     const OUString &rLocalName,
03478     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03479 {
03480         return new SmXMLPrescriptsContext_Impl(*this,nPrefix,rLocalName);
03481 }
03482 
03483 SvXMLImportContext *SmXMLImport::CreateAlignGroupContext(sal_uInt16 nPrefix,
03484     const OUString &rLocalName,
03485     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03486 {
03487         return new SmXMLAlignGroupContext_Impl(*this,nPrefix,rLocalName);
03488 }
03489 
03490 SvXMLImportContext *SmXMLImport::CreateActionContext(sal_uInt16 nPrefix,
03491     const OUString &rLocalName,
03492     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
03493 {
03494         return new SmXMLActionContext_Impl(*this,nPrefix,rLocalName);
03495 }
03496 
03497 SmXMLImport::~SmXMLImport() throw ()
03498 {
03499     delete pPresLayoutElemTokenMap;
03500     delete pPresElemTokenMap;
03501     delete pPresScriptEmptyElemTokenMap;
03502     delete pPresTableElemTokenMap;
03503     delete pPresLayoutAttrTokenMap;
03504     delete pFencedAttrTokenMap;
03505     delete pColorTokenMap;
03506     delete pOperatorAttrTokenMap;
03507     delete pAnnotationAttrTokenMap;
03508 }
03509 
03510 void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
03511 {
03512     uno::Reference <frame::XModel> xModel = GetModel();
03513     if( !xModel.is() )
03514         return;
03515 
03516     uno::Reference <lang::XUnoTunnel> xTunnel;
03517     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
03518     SmModel *pModel = reinterpret_cast<SmModel *>
03519         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
03520 
03521     if( !pModel )
03522         return;
03523 
03524     SmDocShell *pDocShell =
03525         static_cast<SmDocShell*>(pModel->GetObjectShell());
03526     if( !pDocShell )
03527         return;
03528 
03529     Rectangle aRect( pDocShell->GetVisArea() );
03530 
03531     sal_Int32 nCount = aViewProps.getLength();
03532     const PropertyValue *pValue = aViewProps.getConstArray();
03533 
03534     long nTmp = 0;
03535     //sal_Bool bShowDeletes = sal_False, bShowInserts = sal_False, bShowFooter = sal_False, bShowHeader = sal_False;
03536 
03537     for (sal_Int32 i = 0; i < nCount ; i++)
03538     {
03539         if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaTop" ) ) )
03540         {
03541             pValue->Value >>= nTmp;
03542             aRect.setY( nTmp );
03543         }
03544         else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaLeft" ) ) )
03545         {
03546             pValue->Value >>= nTmp;
03547             aRect.setX( nTmp );
03548         }
03549         else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaWidth" ) ) )
03550         {
03551             pValue->Value >>= nTmp;
03552                         Size aSize( aRect.GetSize() );
03553                         aSize.Width() = nTmp;
03554             aRect.SetSize( aSize );
03555         }
03556         else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaHeight" ) ) )
03557         {
03558             pValue->Value >>= nTmp;
03559                         Size aSize( aRect.GetSize() );
03560                         aSize.Height() = nTmp;
03561             aRect.SetSize( aSize );
03562         }
03563         pValue++;
03564     }
03565 
03566     pDocShell->SetVisArea ( aRect );
03567 }
03568 
03569 void SmXMLImport::SetConfigurationSettings(const Sequence<PropertyValue>& aConfProps)
03570 {
03571         uno::Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
03572         if ( xProps.is() )
03573         {
03574                 Reference < XPropertySetInfo > xInfo ( xProps->getPropertySetInfo() );
03575                 if (xInfo.is() )
03576                 {
03577                         sal_Int32 nCount = aConfProps.getLength();
03578                         const PropertyValue* pValues = aConfProps.getConstArray();
03579 
03580             const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
03581             const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
03582             const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
03583                         while( nCount-- )
03584                         {
03585                 if (pValues->Name != sFormula &&
03586                     pValues->Name != sBasicLibraries &&
03587                     pValues->Name != sDialogLibraries)
03588                 {
03589                     try
03590                     {
03591                         if( xInfo->hasPropertyByName( pValues->Name ) )
03592                             xProps->setPropertyValue( pValues->Name, pValues->Value );
03593                     }
03594                     catch( Exception& )
03595                     {
03596                         DBG_ERROR( "SmXMLImport::SetConfigurationSettings: Exception!" );
03597                     }
03598                 }
03599 
03600                                 pValues++;
03601                         }
03602                 }
03603         }
03604 }
03605 void SmXMLExport::_ExportContent()
03606 {
03607     SvXMLElementExport aEquation(*this,XML_NAMESPACE_MATH,XML_MATH, sal_True,
03608         sal_True);
03609     SvXMLElementExport *pSemantics=0;
03610 
03611     if (aText.Len())
03612     {
03613         pSemantics = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03614             XML_SEMANTICS, sal_True, sal_True);
03615     }
03616 
03617     ExportNodes(pTree,0);
03618 
03619     if (aText.Len())
03620     {
03621         // Convert symbol names
03622         uno::Reference <frame::XModel> xModel = GetModel();
03623         uno::Reference <lang::XUnoTunnel> xTunnel;
03624         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
03625         SmModel *pModel = reinterpret_cast<SmModel *>
03626             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
03627         SmDocShell *pDocShell = pModel ?
03628             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
03629         DBG_ASSERT( pDocShell, "doc shell missing" );
03630         if (pDocShell)
03631         {
03632             SmParser &rParser = pDocShell->GetParser();
03633             BOOL bVal = rParser.IsExportSymbolNames();
03634             rParser.SetExportSymbolNames( TRUE );
03635             SmNode *pTmpTree = rParser.Parse( aText );
03636             aText = rParser.GetText();
03637             delete pTmpTree;
03638             rParser.SetExportSymbolNames( bVal );
03639         }
03640 
03641         AddAttribute(XML_NAMESPACE_MATH,XML_ENCODING,
03642             OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
03643         SvXMLElementExport aAnnotation(*this,XML_NAMESPACE_MATH,
03644             XML_ANNOTATION,sal_True, sal_False);
03645         GetDocHandler()->characters(OUString( aText ));
03646     }
03647     delete pSemantics;
03648 }
03649 
03650 void SmXMLExport::GetViewSettings( Sequence < PropertyValue >& aProps)
03651 {
03652     uno::Reference <frame::XModel> xModel = GetModel();
03653     if( !xModel.is() )
03654         return;
03655 
03656     uno::Reference <lang::XUnoTunnel> xTunnel;
03657     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
03658     SmModel *pModel = reinterpret_cast<SmModel *>
03659         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
03660 
03661     if( !pModel )
03662         return;
03663 
03664     SmDocShell *pDocShell =
03665         static_cast<SmDocShell*>(pModel->GetObjectShell());
03666     if( !pDocShell )
03667         return;
03668 
03669     aProps.realloc( 4 );
03670     PropertyValue *pValue = aProps.getArray();
03671     sal_Int32 nIndex = 0;
03672 
03673     Rectangle aRect( pDocShell->GetVisArea() );
03674 
03675     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
03676     pValue[nIndex++].Value <<= aRect.Top();
03677 
03678     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
03679     pValue[nIndex++].Value <<= aRect.Left();
03680 
03681     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
03682     pValue[nIndex++].Value <<= aRect.GetWidth();
03683 
03684     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
03685     pValue[nIndex++].Value <<= aRect.GetHeight();
03686 }
03687 
03688 void SmXMLExport::GetConfigurationSettings( Sequence < PropertyValue > & rProps)
03689 {
03690         Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
03691         if ( xProps.is() )
03692         {
03693                 Reference< XPropertySetInfo > xPropertySetInfo = xProps->getPropertySetInfo();
03694                 if (xPropertySetInfo.is())
03695                 {
03696                         Sequence< Property > aProps = xPropertySetInfo->getProperties();
03697                         sal_Int32 nCount(aProps.getLength());
03698                         if (nCount)
03699                         {
03700                                 rProps.realloc(nCount);
03701                                 PropertyValue* pProps = rProps.getArray();
03702                                 if (pProps)
03703                                 {
03704                     const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
03705                     const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
03706                     const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
03707                     const OUString sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
03708                     for (sal_Int32 i = 0; i < nCount; i++, pProps++)
03709                     {
03710                         const OUString &rPropName = aProps[i].Name;
03711                         if (rPropName != sFormula &&
03712                             rPropName != sBasicLibraries &&
03713                             rPropName != sDialogLibraries &&
03714                             rPropName != sRuntimeUID)
03715                         {
03716                             pProps->Name = rPropName;
03717                             pProps->Value = xProps->getPropertyValue(rPropName);
03718                         }
03719                     }
03720                                 }
03721                         }
03722                 }
03723         }
03724 }
03725 
03726 void SmXMLExport::ExportLine(const SmNode *pNode,int nLevel)
03727 {
03728     ExportExpression(pNode,nLevel);
03729 }
03730 
03731 void SmXMLExport::ExportBinaryHorizontal(const SmNode *pNode,int nLevel)
03732 {
03733     ExportExpression(pNode,nLevel);
03734 }
03735 
03736 void SmXMLExport::ExportUnaryHorizontal(const SmNode *pNode,int nLevel)
03737 {
03738     ExportExpression(pNode,nLevel);
03739 }
03740 
03741 void SmXMLExport::ExportExpression(const SmNode *pNode,int nLevel)
03742 {
03743     SvXMLElementExport *pRow=0;
03744     ULONG  nSize = pNode->GetNumSubNodes();
03745 
03746     if (nSize > 1)
03747         pRow = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MROW,
03748         sal_True, sal_True);
03749 
03750     //if (nSize)
03751     //{
03752         for (USHORT i = 0; i < nSize; i++)
03753             if (const SmNode *pTemp = pNode->GetSubNode(i))
03754                 ExportNodes(pTemp,nLevel+1);
03755     //}
03756 #if 0
03757     else
03758     {
03759         //This saves us from situations like "a newline" where the
03760         //lack of a term following the newline would otherwise create
03761         //a incorrect token like <mtr/>
03762         SvXMLElementExport aDummy(*this,XML_NAMESPACE_MATH,XML_MI,
03763             sal_True,sal_True);
03764         sal_Unicode nArse[2] = {'\n','\0'};
03765         GetDocHandler()->characters(nArse);
03766     }
03767 #endif
03768 
03769     delete pRow;
03770 }
03771 
03772 void SmXMLExport::ExportBinaryVertical(const SmNode *pNode,int nLevel)
03773 {
03774     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Fraction");
03775     SvXMLElementExport aFraction(*this,XML_NAMESPACE_MATH,XML_MFRAC, sal_True,
03776         sal_True);
03777     ExportNodes(pNode->GetSubNode(0),nLevel);
03778     ExportNodes(pNode->GetSubNode(2),nLevel);
03779 }
03780 
03781 void SmXMLExport::ExportTable(const SmNode *pNode, int nLevel)
03782 {
03783     SvXMLElementExport *pTable=0;
03784 
03785     USHORT nSize = pNode->GetNumSubNodes();
03786 
03787     //If the list ends in newline then the last entry has
03788     //no subnodes, the newline is superfulous so we just drop
03789     //the last node, inclusion would create a bad MathML
03790     //table
03791     if (pNode->GetSubNode(nSize-1)->GetNumSubNodes() == 0)
03792         nSize--;
03793 
03794     if ( nLevel || (nSize >1))
03795         pTable = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MTABLE,
03796         sal_True, sal_True);
03797 
03798     for (USHORT i = 0; i < nSize; i++)
03799         if (const SmNode *pTemp = pNode->GetSubNode(i))
03800         {
03801             SvXMLElementExport *pRow=0;
03802             if (pTable)
03803                 pRow = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03804                     XML_MTR, sal_True, sal_True);
03805             ExportNodes(pTemp,nLevel+1);
03806             delete pRow;
03807         }
03808 
03809     delete pTable;
03810 }
03811 
03812 void SmXMLExport::ExportMath(const SmNode *pNode, int /*nLevel*/)
03813 {
03814         const SmMathSymbolNode *pTemp = static_cast<const SmMathSymbolNode *>
03815                 (pNode);
03816         SvXMLElementExport aMath(*this,XML_NAMESPACE_MATH,XML_MO,
03817                 sal_True,sal_False);
03818         sal_Unicode nArse[2];
03819         nArse[0] = pTemp->GetText().GetChar(0);
03820         sal_Unicode cTmp = ConvertMathToMathML( nArse[0] );
03821         if (cTmp != 0)
03822                 nArse[0] = cTmp;
03823     DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
03824         nArse[1] = 0;
03825         GetDocHandler()->characters(nArse);
03826 }
03827 
03828 void SmXMLExport::ExportText(const SmNode *pNode, int /*nLevel*/)
03829 {
03830     SvXMLElementExport *pText;
03831     const SmTextNode *pTemp = static_cast<const SmTextNode *>(pNode);
03832     switch (pNode->GetToken().eType)
03833     {
03834         default:
03835         case TIDENT:
03836         {
03837             //Note that we change the fontstyle to italic for strings that
03838             //are italic and longer than a single character.
03839             sal_Bool bIsItalic = IsItalic( pTemp->GetFont() );
03840             if ((pTemp->GetText().Len() > 1) && bIsItalic)
03841                 AddAttribute(XML_NAMESPACE_MATH,XML_FONTSTYLE,
03842                 XML_ITALIC);
03843             else if ((pTemp->GetText().Len() == 1) && !bIsItalic)
03844                 AddAttribute(XML_NAMESPACE_MATH,XML_FONTSTYLE,
03845                 XML_NORMAL);
03846             pText = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MI,
03847             sal_True,sal_False);
03848             break;
03849         }
03850         case TNUMBER:
03851             pText = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MN,
03852             sal_True,sal_False);
03853             break;
03854         case TTEXT:
03855             pText = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MTEXT,
03856             sal_True,sal_False);
03857             break;
03858         }
03859     GetDocHandler()->characters(OUString(pTemp->GetText().GetBuffer()));
03860     delete pText;
03861 }
03862 
03863 void SmXMLExport::ExportBlank(const SmNode * /*pNode*/, int /*nLevel*/)
03864 {
03868 
03869     SvXMLElementExport *pText;
03870     //const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
03871 
03872     pText = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MI,
03873                     sal_True,sal_False);
03874     
03875     GetDocHandler()->characters( OUString() );
03876     delete pText;
03877 }
03878 
03879 void SmXMLExport::ExportSubSupScript(const SmNode *pNode,int nLevel)
03880 {
03881     const SmNode *pSub  = 0;
03882     const SmNode *pSup  = 0;
03883     const SmNode *pCSub = 0;
03884     const SmNode *pCSup = 0;
03885     const SmNode *pLSub = 0;
03886     const SmNode *pLSup = 0;
03887     SvXMLElementExport *pThing = 0, *pThing2 = 0;
03888 
03889     //if we have prescripts at all then we must use the tensor notation
03890 
03891     //This is one of those excellent locations where scope is vital to
03892     //arrange the construction and destruction of the element helper
03893     //classes correctly
03894     pLSub = pNode->GetSubNode(LSUB+1);
03895     pLSup = pNode->GetSubNode(LSUP+1);
03896     if (pLSub || pLSup)
03897     {
03898         SvXMLElementExport aMultiScripts(*this,XML_NAMESPACE_MATH,
03899             XML_MMULTISCRIPTS, sal_True, sal_True);
03900 
03901 
03902         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
03903             && NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
03904         {
03905             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03906                 XML_MUNDEROVER, sal_True,sal_True);
03907         }
03908         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
03909         {
03910             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03911                 XML_MUNDER, sal_True,sal_True);
03912         }
03913         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
03914         {
03915             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03916                 XML_MOVER, sal_True,sal_True);
03917         }
03918 
03919         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
03920 
03921         if (pCSub)
03922             ExportNodes(pCSub, nLevel+1);
03923         if (pCSup)
03924             ExportNodes(pCSup, nLevel+1);
03925         delete pThing2;
03926 
03927         pSub = pNode->GetSubNode(RSUB+1);
03928         pSup = pNode->GetSubNode(RSUP+1);
03929         if (pSub || pSup)
03930         {
03931             if (pSub)
03932                 ExportNodes(pSub, nLevel+1);
03933             else
03934             {
03935                 SvXMLElementExport aNone(*this,XML_NAMESPACE_MATH, XML_NONE,
03936                     sal_True,sal_True);
03937             }
03938             if (pSup)
03939                 ExportNodes(pSup, nLevel+1);
03940             else
03941             {
03942                 SvXMLElementExport aNone(*this,XML_NAMESPACE_MATH, XML_NONE,
03943                     sal_True,sal_True);
03944             }
03945         }
03946 
03947         //Seperator element between suffix and prefix sub/sup pairs
03948         {
03949             SvXMLElementExport aPrescripts(*this,XML_NAMESPACE_MATH,
03950                 XML_MPRESCRIPTS, sal_True,sal_True);
03951         }
03952 
03953         if (pLSub)
03954             ExportNodes(pLSub, nLevel+1);
03955         else
03956         {
03957             SvXMLElementExport aNone(*this,XML_NAMESPACE_MATH, XML_NONE,
03958                 sal_True,sal_True);
03959 
03960         }
03961         if (pLSup)
03962             ExportNodes(pLSup, nLevel+1);
03963         else
03964         {
03965             SvXMLElementExport aNone(*this,XML_NAMESPACE_MATH, XML_NONE,
03966                 sal_True,sal_True);
03967 
03968         }
03969     }
03970     else
03971     {
03972         if (NULL != (pSub = pNode->GetSubNode(RSUB+1)) &&
03973             NULL != (pSup = pNode->GetSubNode(RSUP+1)))
03974         {
03975             pThing = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03976                 XML_MSUBSUP, sal_True,sal_True);
03977         }
03978         else if (NULL != (pSub = pNode->GetSubNode(RSUB+1)))
03979         {
03980             pThing = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MSUB,
03981                 sal_True,sal_True);
03982         }
03983         else if (NULL != (pSup = pNode->GetSubNode(RSUP+1)))
03984         {
03985             pThing = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MSUP,
03986                 sal_True,sal_True);
03987         }
03988 
03989         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
03990             && NULL != (pCSup=pNode->GetSubNode(CSUP+1)))
03991         {
03992             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03993                 XML_MUNDEROVER, sal_True,sal_True);
03994         }
03995         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
03996         {
03997             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
03998                 XML_MUNDER, sal_True,sal_True);
03999         }
04000         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
04001         {
04002             pThing2 = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
04003                 XML_MOVER, sal_True,sal_True);
04004         }
04005         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
04006 
04007         if (pCSub)
04008             ExportNodes(pCSub, nLevel+1);
04009         if (pCSup)
04010             ExportNodes(pCSup, nLevel+1);
04011         delete pThing2;
04012 
04013         if (pSub)
04014             ExportNodes(pSub, nLevel+1);
04015         if (pSup)
04016             ExportNodes(pSup, nLevel+1);
04017         delete pThing;
04018     }
04019 }
04020 
04021 void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
04022 {
04023         const SmNode *pTemp;
04024     const SmNode *pLeft=pNode->GetSubNode(0);
04025     const SmNode *pRight=pNode->GetSubNode(2);
04026         SvXMLElementExport *pFences=0,*pRow=0;
04027         if ( ((pLeft) && (pLeft->GetToken().eType != TNONE)) &&
04028                 ((pRight) && (pRight->GetToken().eType != TNONE)) &&
04029                 (pNode->GetScaleMode() == SCALE_HEIGHT))
04030         {
04031                 sal_Unicode nArse[2];
04032                 nArse[1] = 0;
04033         nArse[0] = static_cast<
04034             const SmMathSymbolNode* >(pLeft)->GetText().GetChar(0);
04035         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
04036                 AddAttribute(XML_NAMESPACE_MATH,XML_OPEN,nArse);
04037         nArse[0] = static_cast<
04038             const SmMathSymbolNode* >(pRight)->GetText().GetChar(0);
04039         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
04040                 AddAttribute(XML_NAMESPACE_MATH,XML_CLOSE,nArse);
04041                 pFences = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MFENCED,
04042                         sal_True,sal_True);
04043         }
04044         else if (pLeft && (pLeft->GetToken().eType != TNONE))
04045         {
04046                 pRow = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MROW,
04047                         sal_True, sal_True);
04048                 if (pNode->GetScaleMode() == SCALE_HEIGHT)
04049                         AddAttribute(XML_NAMESPACE_MATH,XML_STRETCHY,XML_TRUE);
04050                 else
04051                         AddAttribute(XML_NAMESPACE_MATH,XML_STRETCHY,XML_FALSE);
04052                 ExportNodes(pLeft,nLevel+1);
04053         }
04054         else
04055                 pRow = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MROW,
04056                         sal_True, sal_True);
04057 
04058     if (NULL != (pTemp = pNode->GetSubNode(1)))
04059         ExportNodes(pTemp,nLevel+1);
04060     if (pFences)
04061         delete pFences;
04062     else if (pRight && (pRight->GetToken().eType != TNONE))
04063     {
04064         if (pNode->GetScaleMode() == SCALE_HEIGHT)
04065             AddAttribute(XML_NAMESPACE_MATH,XML_STRETCHY,XML_TRUE);
04066         else
04067             AddAttribute(XML_NAMESPACE_MATH,XML_STRETCHY,XML_FALSE);
04068         ExportNodes(pRight,nLevel+1);
04069     }
04070     delete pRow;
04071 }
04072 
04073 void SmXMLExport::ExportRoot(const SmNode *pNode, int nLevel)
04074 {
04075     if (pNode->GetSubNode(0))
04076     {
04077         SvXMLElementExport aRoot(*this,XML_NAMESPACE_MATH,XML_MROOT,sal_True,
04078             sal_True);
04079         ExportNodes(pNode->GetSubNode(2),nLevel+1);
04080         ExportNodes(pNode->GetSubNode(0),nLevel+1);
04081     }
04082     else
04083     {
04084         SvXMLElementExport aSqrt(*this,XML_NAMESPACE_MATH,XML_MSQRT,sal_True,
04085             sal_True);
04086         ExportNodes(pNode->GetSubNode(2),nLevel+1);
04087     }
04088 }
04089 
04090 void SmXMLExport::ExportOperator(const SmNode *pNode, int nLevel)
04091 {
04092     /*we need to either use content or font and size attributes
04093      *here*/
04094 #if 0
04095     {
04096     SvXMLElementExport aMath(*this,XML_NAMESPACE_MATH,XML_MO,
04097         sal_True,sal_False);
04098     SmTextNode *pTemp = (SmTextNode *)pNode->GetSubNode(0);
04099     GetDocHandler()->characters(pTemp->GetText());
04100     }
04101 #endif
04102     SvXMLElementExport aRow(*this,XML_NAMESPACE_MATH,XML_MROW,
04103         sal_True, sal_True);
04104     ExportNodes(pNode->GetSubNode(0),nLevel+1);
04105     ExportNodes(pNode->GetSubNode(1),nLevel+1);
04106 }
04107 
04108 void SmXMLExport::ExportAttributes(const SmNode *pNode, int nLevel)
04109 {
04110     SvXMLElementExport *pElement=0;
04111 
04112     if (pNode->GetToken().eType == TUNDERLINE)
04113     {
04114         AddAttribute(XML_NAMESPACE_MATH,XML_ACCENTUNDER,
04115             XML_TRUE);
04116         pElement = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MUNDER,
04117             sal_True,sal_True);
04118     }
04119     else if (pNode->GetToken().eType != TOVERSTRIKE)
04120     {
04121         AddAttribute(XML_NAMESPACE_MATH,XML_ACCENT,
04122             XML_TRUE);
04123         pElement = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,XML_MOVER,
04124             sal_True,sal_True);
04125     }
04126 
04127     ExportNodes(pNode->GetSubNode(1),nLevel+1);
04128     switch (pNode->GetToken().eType)
04129     {
04130         case TOVERLINE:
04131             {
04132             //proper entity support required
04133             SvXMLElementExport aMath(*this,XML_NAMESPACE_MATH,XML_MO,
04134                 sal_True,sal_False);
04135 #if 0
04136             GetDocHandler()->characters(
04137                 OUString(RTL_CONSTASCII_USTRINGPARAM("&overbar;")));
04138 #else
04139             sal_Unicode nArse[2] = {0xAF,0x00};
04140 #endif
04141             GetDocHandler()->characters(nArse);
04142             }
04143             break;
04144         case TUNDERLINE:
04145             {
04146             //proper entity support required
04147             SvXMLElementExport aMath(*this,XML_NAMESPACE_MATH,XML_MO,
04148                 sal_True,sal_False);
04149 #if 0
04150             GetDocHandler()->characters(
04151                 OUString(RTL_CONSTASCII_USTRINGPARAM("&underbar;")));
04152 #else
04153             sal_Unicode nArse[2] = {0x0332,0x00};
04154 #endif
04155             GetDocHandler()->characters(nArse);
04156             }
04157             break;
04158         case TOVERSTRIKE:
04159             break;
04160         default:
04161             ExportNodes(pNode->GetSubNode(0),nLevel+1);
04162             break;
04163     }
04164     delete pElement;
04165 }
04166 
04167 void SmXMLExport::ExportFont(const SmNode *pNode, int nLevel)
04168 {
04169     SvXMLElementExport *pElement=0;
04170     switch (pNode->GetToken().eType)
04171     {
04172         //wrap a phantom element around everything*/
04173         case TPHANTOM:
04174             pElement = new SvXMLElementExport(*this,XML_NAMESPACE_MATH,
04175                 XML_MPHANTOM, sal_True,sal_True);
04176             break;
04177         case TBOLD:
04178             AddAttribute(XML_NAMESPACE_MATH,XML_FONTWEIGHT,
04179                 XML_BOLD);
04180             break;
04181         case TITALIC:
04182             AddAttribute(XML_NAMESPACE_MATH,XML_FONTSTYLE,
04183                 XML_ITALIC);
04184             break;
04185         case TNBOLD:
04186             AddAttribute(XML_NAMESPACE_MATH,XML_FONTWEIGHT,
04187                 XML_WEIGHT_NORMAL);
04188             break;
04189         case TNITALIC:
04190             AddAttribute(XML_NAMESPACE_MATH,XML_FONTSTYLE,
04191                 XML_WEIGHT_NORMAL);
04192             break;
04193         case TBLACK:
04194             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04195                 XML_BLACK);
04196             break;
04197         case TWHITE:
04198             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04199                 XML_WHITE);
04200             break;
04201         case TRED:
04202             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04203                 XML_RED);
04204             break;
04205         case TGREEN:
04206             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04207                 XML_GREEN);
04208             break;
04209         case TBLUE:
04210             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04211                 XML_BLUE);
04212             break;
04213         case TCYAN:
04214             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04215                 XML_AQUA);
04216             break;
04217         case TMAGENTA:
04218             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04219                 XML_FUCHSIA);
04220             break;
04221         case TYELLOW:
04222             AddAttribute(XML_NAMESPACE_MATH,XML_COLOR,
04223                 XML_YELLOW);
04224             break;
04225         case TSIZE:
04226             {
04227             const SmFontNode *pFontNode = static_cast<const SmFontNode *>
04228                 (pNode);
04229             const Fraction &aFrac = pFontNode->GetSizeParameter();
04230 
04231             OUStringBuffer sStrBuf;
04232             switch(pFontNode->GetSizeType())
04233             {
04234                 case FNTSIZ_MULTIPLY:
04235                     SvXMLUnitConverter::convertDouble(sStrBuf,
04236                         static_cast<double>(aFrac*Fraction(100.00)));
04237                     sStrBuf.append(static_cast<sal_Unicode>('%'));
04238                     break;
04239                 case FNTSIZ_DIVIDE:
04240                     SvXMLUnitConverter::convertDouble(sStrBuf,
04241                         static_cast<double>(Fraction(100.00)/aFrac));
04242                     sStrBuf.append(static_cast<sal_Unicode>('%'));
04243                     break;
04244                 case FNTSIZ_ABSOLUT:
04245                     SvXMLUnitConverter::convertDouble(sStrBuf,
04246                         static_cast<double>(aFrac));
04247                     sStrBuf.append(
04248                         GetXMLToken(XML_UNIT_PT));
04249                     break;
04250                 default:
04251                     {
04252                         //The problem here is that the wheels fall off because
04253                         //font size is stored in 100th's of a mm not pts, and
04254                         //rounding errors take their toll on the original
04255                         //value specified in points.
04256 
04257                         //Must fix StarMath to retain the original pt values
04258                         Fraction aTemp = Sm100th_mmToPts(pFontNode->GetFont().
04259                             GetSize().Height());
04260 
04261                         if (pFontNode->GetSizeType() == FNTSIZ_MINUS)
04262                             aTemp-=aFrac;
04263                         else
04264                             aTemp+=aFrac;
04265 
04266                         double mytest = static_cast<double>(aTemp);
04267 
04268                         mytest = ::rtl::math::round(mytest,1);
04269                         SvXMLUnitConverter::convertDouble(sStrBuf,mytest);
04270                         sStrBuf.append(GetXMLToken(XML_UNIT_PT));
04271                     }
04272                     break;
04273             }
04274 
04275             OUString sStr(sStrBuf.makeStringAndClear());
04276             AddAttribute(XML_NAMESPACE_MATH,XML_FONTSIZE,sStr);
04277             }
04278             break;
04279         case TFIXED:
04280         case TSANS:
04281         case TSERIF:
04282             AddAttribute(XML_NAMESPACE_MATH,XML_FONTFAMILY,
04283                 OUString(pNode->GetToken().aText.GetBuffer()));
04284             break;
04285         default:
04286             break;
04287 
04288     }
04289 #if 0
04290     if (pNode->GetNumSubNodes() > 1) //or in the future is a node that
04291                                      //cannot take the currently supported
04292                                      //properties
04293 #endif
04294     //for now we will just always export with a style and not worry about
04295     //anyone else for the moment.
04296     {
04297         //wrap a style around it
04298         SvXMLElementExport aStyle(*this,XML_NAMESPACE_MATH,
04299                 XML_MSTYLE, sal_True,sal_True);
04300         ExportExpression(pNode,nLevel);
04301     }
04302 #if 0
04303     else
04304         ExportNodes(pNode->GetSubNode(0),nLevel+1);
04305 #endif
04306 
04307     delete pElement;
04308 }
04309 
04310 
04311 void SmXMLExport::ExportVerticalBrace(const SmNode *pNode, int nLevel)
04312 {
04313     //Place the overbrace value OVER a vertical brace and then place that
04314     //expression OVER the overbrace value, If someone can find a
04315     //dedicated term in MathML to handle this overbrace/underbrace concept
04316     //let me know. C.
04317     XMLTokenEnum which;
04318 
04319     switch (pNode->GetToken().eType)
04320     {
04321         case TOVERBRACE:
04322         default:
04323             which = XML_MOVER;
04324             break;
04325         case TUNDERBRACE:
04326             which = XML_MUNDER;
04327             break;
04328     }
04329 
04330     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Vertical Brace");
04331     SvXMLElementExport aOver1(*this,XML_NAMESPACE_MATH,which, sal_True,
04332         sal_True);
04333     {//Scoping
04334         AddAttribute(XML_NAMESPACE_MATH,XML_ACCENT,XML_TRUE);
04335         SvXMLElementExport aOver2(*this,XML_NAMESPACE_MATH,which, sal_True,
04336             sal_True);
04337         ExportNodes(pNode->GetSubNode(0),nLevel);
04338         ExportNodes(pNode->GetSubNode(1),nLevel);
04339     }
04340     ExportNodes(pNode->GetSubNode(2),nLevel);
04341 }
04342 
04343 void SmXMLExport::ExportMatrix(const SmNode *pNode, int nLevel)
04344 {
04345     SvXMLElementExport aTable(*this,XML_NAMESPACE_MATH,XML_MTABLE,
04346         sal_True, sal_True);
04347     const SmMatrixNode *pMatrix = static_cast<const SmMatrixNode *>(pNode);
04348     USHORT i=0;
04349     for (ULONG y = 0; y < pMatrix->GetNumRows(); y++)
04350     {
04351         SvXMLElementExport aRow(*this,XML_NAMESPACE_MATH,XML_MTR,
04352             sal_True, sal_True);
04353         for (ULONG x = 0; x < pMatrix->GetNumCols(); x++)
04354             if (const SmNode *pTemp = pNode->GetSubNode(i++))
04355             {
04356                 SvXMLElementExport aCell(*this,XML_NAMESPACE_MATH,
04357                         XML_MTD, sal_True, sal_True);
04358                 ExportNodes(pTemp,nLevel+1);
04359             }
04360     }
04361 }
04362 
04363 void SmXMLExport::ExportNodes(const SmNode *pNode, int nLevel)
04364 {
04365     if (!pNode)
04366         return;
04367     switch(pNode->GetType())
04368     {
04369         case NTABLE:
04370             ExportTable(pNode,nLevel);
04371             break;
04372         case NALIGN:
04373         case NBRACEBODY:
04374         case NEXPRESSION:
04375             ExportExpression(pNode,nLevel);
04376             break;
04377         case NLINE:
04378             ExportLine(pNode,nLevel);
04379             break;
04380         case NTEXT:
04381             ExportText(pNode,nLevel);
04382             break;
04383         case NSPECIAL: //NSPECIAL requires some sort of Entity preservation in
04384                     //the XML engine.
04385         case NMATH:
04386                         {
04387             //To fully handle generic MathML we need to implement the full
04388             //operator dictionary, we will generate MathML with explicit
04389             //stretchiness for now.
04390             sal_Int16 nLength = GetAttrList().getLength();
04391             sal_Bool bAddStretch=sal_True;
04392             for( sal_Int16 i = 0; i < nLength; i++ )
04393             {
04394                                 OUString sLocalName;
04395                 sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName(
04396                                         GetAttrList().getNameByIndex(i), &sLocalName );
04397 
04398                                 if ( ( XML_NAMESPACE_MATH == nPrefix ) &&
04399                                         IsXMLToken(sLocalName, XML_STRETCHY) )
04400                 {
04401                     bAddStretch = sal_False;
04402                     break;
04403                 }
04404             }
04405             if (bAddStretch)
04406                         {
04407                 AddAttribute(XML_NAMESPACE_MATH,XML_STRETCHY,XML_FALSE);
04408                         }
04409             ExportMath(pNode,nLevel);
04410                         }
04411             break;
04412         case NBINHOR:
04413             ExportBinaryHorizontal(pNode,nLevel);
04414             break;
04415         case NUNHOR:
04416             ExportUnaryHorizontal(pNode,nLevel);
04417             break;
04418         case NBRACE:
04419             ExportBrace(pNode,nLevel);
04420             break;
04421         case NBINVER:
04422             ExportBinaryVertical(pNode,nLevel);
04423             break;
04424         case NSUBSUP:
04425             ExportSubSupScript(pNode,nLevel);
04426             break;
04427         case NROOT:
04428             ExportRoot(pNode,nLevel);
04429             break;
04430         case NOPER:
04431             ExportOperator(pNode,nLevel);
04432             break;
04433         case NATTRIBUT:
04434             ExportAttributes(pNode,nLevel);
04435             break;
04436         case NFONT:
04437             ExportFont(pNode,nLevel);
04438             break;
04439         case NVERTICAL_BRACE:
04440             ExportVerticalBrace(pNode,nLevel);
04441             break;
04442         case NMATRIX:
04443             ExportMatrix(pNode,nLevel);
04444             break;
04445         case NBLANK:
04446             ExportBlank(pNode,nLevel);
04447             break;
04448        default:
04449             break;
04450 
04451 #if 0
04452         default:
04453             {
04454             ULONG  nSize = pNode->GetNumSubNodes();
04455             for (ULONG i = 0; i < nSize; i++)
04456                 if (SmNode *pTemp = pNode->GetSubNode(i))
04457                     ExportNodes(pTemp,nLevel+1);
04458             }
04459             break;
04460 #endif
04461     }
04462 }

Generated on Wed Feb 20 17:21:57 2008 for maths by  doxygen 1.5.1