LCOV - code coverage report
Current view: top level - starmath/source - mathmlimport.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 640 1276 50.2 %
Date: 2015-06-13 12:38:46 Functions: 115 237 48.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : /*todo: Change characters and tcharacters to accumulate the characters together
      22             : into one string, xml parser hands them to us line by line rather than all in
      23             : one go*/
      24             : 
      25             : #include <com/sun/star/xml/sax/XErrorHandler.hpp>
      26             : #include <com/sun/star/xml/sax/XEntityResolver.hpp>
      27             : #include <com/sun/star/xml/sax/InputSource.hpp>
      28             : #include <com/sun/star/xml/sax/XDTDHandler.hpp>
      29             : #include <com/sun/star/xml/sax/Parser.hpp>
      30             : #include <com/sun/star/io/XActiveDataSource.hpp>
      31             : #include <com/sun/star/io/XActiveDataControl.hpp>
      32             : #include <com/sun/star/document/XDocumentProperties.hpp>
      33             : #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
      34             : #include <com/sun/star/packages/zip/ZipIOException.hpp>
      35             : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
      36             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      37             : #include <com/sun/star/container/XNameAccess.hpp>
      38             : #include <com/sun/star/embed/ElementModes.hpp>
      39             : #include <com/sun/star/uno/Any.h>
      40             : 
      41             : #include <comphelper/genericpropertyset.hxx>
      42             : #include <comphelper/processfactory.hxx>
      43             : #include <comphelper/servicehelper.hxx>
      44             : #include <comphelper/string.hxx>
      45             : #include <rtl/math.hxx>
      46             : #include <sfx2/frame.hxx>
      47             : #include <sfx2/docfile.hxx>
      48             : #include <osl/diagnose.h>
      49             : #include <svtools/sfxecode.hxx>
      50             : #include <unotools/saveopt.hxx>
      51             : #include <svl/stritem.hxx>
      52             : #include <svl/itemprop.hxx>
      53             : #include <unotools/streamwrap.hxx>
      54             : #include <sax/tools/converter.hxx>
      55             : #include <xmloff/xmlnmspe.hxx>
      56             : #include <xmloff/xmltoken.hxx>
      57             : #include <xmloff/nmspmap.hxx>
      58             : #include <xmloff/attrlist.hxx>
      59             : #include <xmloff/xmluconv.hxx>
      60             : #include <xmloff/xmlmetai.hxx>
      61             : #include <osl/mutex.hxx>
      62             : 
      63             : #include <memory>
      64             : 
      65             : #include "mathmlimport.hxx"
      66             : #include "register.hxx"
      67             : #include <starmath.hrc>
      68             : #include <unomodel.hxx>
      69             : #include <document.hxx>
      70             : #include <utility.hxx>
      71             : 
      72             : using namespace ::com::sun::star::beans;
      73             : using namespace ::com::sun::star::container;
      74             : using namespace ::com::sun::star::document;
      75             : using namespace ::com::sun::star::lang;
      76             : using namespace ::com::sun::star::uno;
      77             : using namespace ::com::sun::star;
      78             : using namespace ::xmloff::token;
      79             : 
      80             : 
      81             : #define IMPORT_SVC_NAME "com.sun.star.xml.XMLImportFilter"
      82             : 
      83             : 
      84           5 : sal_uLong SmXMLImportWrapper::Import(SfxMedium &rMedium)
      85             : {
      86           5 :     sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
      87             : 
      88           5 :     uno::Reference<uno::XComponentContext> xContext( comphelper::getProcessComponentContext() );
      89             : 
      90             :     //Make a model component from our SmModel
      91          10 :     uno::Reference< lang::XComponent > xModelComp( xModel, uno::UNO_QUERY );
      92             :     OSL_ENSURE( xModelComp.is(), "XMLReader::Read: got no model" );
      93             : 
      94             :     // try to get an XStatusIndicator from the Medium
      95          10 :     uno::Reference<task::XStatusIndicator> xStatusIndicator;
      96             : 
      97           5 :     bool bEmbedded = false;
      98          10 :     uno::Reference <lang::XUnoTunnel> xTunnel;
      99           5 :     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     100             :     SmModel *pModel = reinterpret_cast<SmModel *>
     101           5 :         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
     102             : 
     103             :     SmDocShell *pDocShell = pModel ?
     104           5 :             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
     105           5 :     if (pDocShell)
     106             :     {
     107             :         OSL_ENSURE( pDocShell->GetMedium() == &rMedium,
     108             :                 "different SfxMedium found" );
     109             : 
     110           5 :         SfxItemSet* pSet = rMedium.GetItemSet();
     111           5 :         if (pSet)
     112             :         {
     113             :             const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
     114           5 :                 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
     115           5 :             if (pItem)
     116           0 :                 pItem->GetValue() >>= xStatusIndicator;
     117             :         }
     118             : 
     119           5 :         if ( SfxObjectCreateMode::EMBEDDED == pDocShell->GetCreateMode() )
     120           5 :             bEmbedded = true;
     121             :     }
     122             : 
     123             :     comphelper::PropertyMapEntry aInfoMap[] =
     124             :     {
     125             :         { OUString("PrivateData"), 0,
     126           5 :               cppu::UnoType<XInterface>::get(),
     127             :               beans::PropertyAttribute::MAYBEVOID, 0 },
     128             :         { OUString("BaseURI"), 0,
     129           5 :               ::cppu::UnoType<OUString>::get(),
     130             :               beans::PropertyAttribute::MAYBEVOID, 0 },
     131             :         { OUString("StreamRelPath"), 0,
     132           5 :               ::cppu::UnoType<OUString>::get(),
     133             :               beans::PropertyAttribute::MAYBEVOID, 0 },
     134             :         { OUString("StreamName"), 0,
     135           5 :               ::cppu::UnoType<OUString>::get(),
     136             :               beans::PropertyAttribute::MAYBEVOID, 0 },
     137             :         { OUString(), 0, css::uno::Type(), 0, 0 }
     138          30 :     };
     139             :     uno::Reference< beans::XPropertySet > xInfoSet(
     140             :                 comphelper::GenericPropertySet_CreateInstance(
     141          10 :                             new comphelper::PropertySetInfo( aInfoMap ) ) );
     142             : 
     143             :     // Set base URI
     144          10 :     OUString sPropName( "BaseURI" );
     145           5 :     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL() ) );
     146             : 
     147           5 :     sal_Int32 nSteps=3;
     148           5 :     if ( !(rMedium.IsStorage()))
     149           3 :         nSteps = 1;
     150             : 
     151           5 :     sal_Int32 nProgressRange(nSteps);
     152           5 :     if (xStatusIndicator.is())
     153             :     {
     154           0 :         xStatusIndicator->start(SM_RESSTR(STR_STATSTR_READING), nProgressRange);
     155             :     }
     156             : 
     157           5 :     nSteps=0;
     158           5 :     if (xStatusIndicator.is())
     159           0 :         xStatusIndicator->setValue(nSteps++);
     160             : 
     161           5 :     if ( rMedium.IsStorage())
     162             :     {
     163             :         // TODO/LATER: handle the case of embedded links gracefully
     164           2 :         if ( bEmbedded ) // && !rMedium.GetStorage()->IsRoot() )
     165             :         {
     166           2 :             OUString aName( "dummyObjName" );
     167           2 :             if ( rMedium.GetItemSet() )
     168             :             {
     169             :                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
     170           2 :                     rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
     171           2 :                 if ( pDocHierarchItem )
     172           2 :                     aName = pDocHierarchItem->GetValue();
     173             :             }
     174             : 
     175           2 :             if ( !aName.isEmpty() )
     176             :             {
     177           2 :                 sPropName = "StreamRelPath";
     178           2 :                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
     179           2 :             }
     180             :         }
     181             : 
     182           2 :         bool bOASIS = ( SotStorage::GetVersion( rMedium.GetStorage() ) > SOFFICE_FILEFORMAT_60 );
     183           2 :         if (xStatusIndicator.is())
     184           0 :             xStatusIndicator->setValue(nSteps++);
     185             : 
     186             :         sal_uLong nWarn = ReadThroughComponent(
     187             :             rMedium.GetStorage(), xModelComp, "meta.xml", "Meta.xml",
     188             :             xContext, xInfoSet,
     189             :                 (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaImporter"
     190           2 :                         : "com.sun.star.comp.Math.XMLMetaImporter") );
     191             : 
     192           2 :         if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
     193             :         {
     194           2 :             if (xStatusIndicator.is())
     195           0 :                 xStatusIndicator->setValue(nSteps++);
     196             : 
     197             :             nWarn = ReadThroughComponent(
     198             :                 rMedium.GetStorage(), xModelComp, "settings.xml", 0,
     199             :                 xContext, xInfoSet,
     200             :                 (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsImporter"
     201           2 :                         : "com.sun.star.comp.Math.XMLSettingsImporter" ) );
     202             : 
     203           2 :             if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
     204             :             {
     205           2 :                 if (xStatusIndicator.is())
     206           0 :                     xStatusIndicator->setValue(nSteps++);
     207             : 
     208             :                 nError = ReadThroughComponent(
     209             :                     rMedium.GetStorage(), xModelComp, "content.xml", "Content.xml",
     210           2 :                     xContext, xInfoSet, "com.sun.star.comp.Math.XMLImporter" );
     211             :             }
     212             :             else
     213           0 :                 nError = ERRCODE_IO_BROKENPACKAGE;
     214             :         }
     215             :         else
     216           0 :             nError = ERRCODE_IO_BROKENPACKAGE;
     217             :     }
     218             :     else
     219             :     {
     220             :         Reference<io::XInputStream> xInputStream =
     221           3 :             new utl::OInputStreamWrapper(rMedium.GetInStream());
     222             : 
     223           3 :         if (xStatusIndicator.is())
     224           0 :             xStatusIndicator->setValue(nSteps++);
     225             : 
     226             :         nError = ReadThroughComponent( xInputStream, xModelComp,
     227           3 :             xContext, xInfoSet, "com.sun.star.comp.Math.XMLImporter", false );
     228             :     }
     229             : 
     230           5 :     if (xStatusIndicator.is())
     231           0 :         xStatusIndicator->end();
     232          10 :     return nError;
     233             : }
     234             : 
     235             : 
     236             : /// read a component (file + filter version)
     237           7 : sal_uLong SmXMLImportWrapper::ReadThroughComponent(
     238             :     Reference<io::XInputStream> xInputStream,
     239             :     Reference<XComponent> xModelComponent,
     240             :     Reference<uno::XComponentContext> & rxContext,
     241             :     Reference<beans::XPropertySet> & rPropSet,
     242             :     const sal_Char* pFilterName,
     243             :     bool bEncrypted )
     244             : {
     245           7 :     sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
     246             :     OSL_ENSURE(xInputStream.is(), "input stream missing");
     247             :     OSL_ENSURE(xModelComponent.is(), "document missing");
     248             :     OSL_ENSURE(rxContext.is(), "factory missing");
     249             :     OSL_ENSURE(NULL != pFilterName,"I need a service name for the component!");
     250             : 
     251             :     // prepare ParserInputSrouce
     252           7 :     xml::sax::InputSource aParserInput;
     253           7 :     aParserInput.aInputStream = xInputStream;
     254             : 
     255             :     // get parser
     256          14 :     Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
     257             : 
     258          14 :     Sequence<Any> aArgs( 1 );
     259           7 :     aArgs[0] <<= rPropSet;
     260             : 
     261             :     // get filter
     262             :     Reference< xml::sax::XDocumentHandler > xFilter(
     263          14 :         rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
     264           7 :             OUString::createFromAscii(pFilterName), aArgs, rxContext),
     265          14 :         UNO_QUERY );
     266             :     OSL_ENSURE( xFilter.is(), "Can't instantiate filter component." );
     267           7 :     if ( !xFilter.is() )
     268           0 :         return nError;
     269             : 
     270             :     // connect parser and filter
     271           7 :     xParser->setDocumentHandler( xFilter );
     272             : 
     273             :     // connect model and filter
     274          14 :     Reference < XImporter > xImporter( xFilter, UNO_QUERY );
     275           7 :     xImporter->setTargetDocument( xModelComponent );
     276             : 
     277             :     // finally, parser the stream
     278             :     try
     279             :     {
     280           7 :         xParser->parseStream( aParserInput );
     281             : 
     282           7 :         uno::Reference<lang::XUnoTunnel> xFilterTunnel;
     283          14 :         xFilterTunnel = uno::Reference<lang::XUnoTunnel>
     284           7 :             ( xFilter, uno::UNO_QUERY );
     285             :         SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
     286             :                 sal::static_int_cast< sal_uIntPtr >(
     287           7 :                 xFilterTunnel->getSomething( SmXMLImport::getUnoTunnelId() )));
     288           7 :         if ( pFilter && pFilter->GetSuccess() )
     289           5 :             nError = 0;
     290             :     }
     291           0 :     catch( xml::sax::SAXParseException& r )
     292             :     {
     293             :         // sax parser sends wrapped exceptions,
     294             :         // try to find the original one
     295           0 :         xml::sax::SAXException aSaxEx = *static_cast<xml::sax::SAXException*>(&r);
     296           0 :         bool bTryChild = true;
     297             : 
     298           0 :         while( bTryChild )
     299             :         {
     300           0 :             xml::sax::SAXException aTmp;
     301           0 :             if ( aSaxEx.WrappedException >>= aTmp )
     302           0 :                 aSaxEx = aTmp;
     303             :             else
     304           0 :                 bTryChild = false;
     305           0 :         }
     306             : 
     307           0 :         packages::zip::ZipIOException aBrokenPackage;
     308           0 :         if ( aSaxEx.WrappedException >>= aBrokenPackage )
     309           0 :             return ERRCODE_IO_BROKENPACKAGE;
     310             : 
     311           0 :         if ( bEncrypted )
     312           0 :             nError = ERRCODE_SFX_WRONGPASSWORD;
     313           0 :     }
     314           0 :     catch( const xml::sax::SAXException& r )
     315             :     {
     316           0 :         packages::zip::ZipIOException aBrokenPackage;
     317           0 :         if ( r.WrappedException >>= aBrokenPackage )
     318           0 :             return ERRCODE_IO_BROKENPACKAGE;
     319             : 
     320           0 :         if ( bEncrypted )
     321           0 :             nError = ERRCODE_SFX_WRONGPASSWORD;
     322           0 :     }
     323           0 :     catch( packages::zip::ZipIOException& )
     324             :     {
     325           0 :         nError = ERRCODE_IO_BROKENPACKAGE;
     326             :     }
     327           0 :     catch( io::IOException& )
     328             :     {
     329             :     }
     330             : 
     331          14 :     return nError;
     332             : }
     333             : 
     334             : 
     335           6 : sal_uLong SmXMLImportWrapper::ReadThroughComponent(
     336             :     const uno::Reference< embed::XStorage >& xStorage,
     337             :     Reference<XComponent> xModelComponent,
     338             :     const sal_Char* pStreamName,
     339             :     const sal_Char* pCompatibilityStreamName,
     340             :     Reference<uno::XComponentContext> & rxContext,
     341             :     Reference<beans::XPropertySet> & rPropSet,
     342             :     const sal_Char* pFilterName )
     343             : {
     344             :     OSL_ENSURE(xStorage.is(), "Need storage!");
     345             :     OSL_ENSURE(NULL != pStreamName, "Please, please, give me a name!");
     346             : 
     347             :     // open stream (and set parser input)
     348           6 :     OUString sStreamName = OUString::createFromAscii(pStreamName);
     349          12 :     uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
     350           6 :     if ( !xAccess->hasByName(sStreamName) || !xStorage->isStreamElement(sStreamName) )
     351             :     {
     352             :         // stream name not found! Then try the compatibility name.
     353             :         // do we even have an alternative name?
     354           2 :         if ( pCompatibilityStreamName )
     355           2 :             sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
     356             :     }
     357             : 
     358             :     // get input stream
     359             :     try
     360             :     {
     361           6 :         uno::Reference < io::XStream > xEventsStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
     362             : 
     363             :         // determine if stream is encrypted or not
     364           8 :         uno::Reference < beans::XPropertySet > xProps( xEventsStream, uno::UNO_QUERY );
     365           8 :         Any aAny = xProps->getPropertyValue( "Encrypted" );
     366           4 :         bool bEncrypted = false;
     367           4 :         if ( aAny.getValueType() == cppu::UnoType<bool>::get() )
     368           4 :             aAny >>= bEncrypted;
     369             : 
     370             :         // set Base URL
     371           4 :         if ( rPropSet.is() )
     372             :         {
     373           4 :             OUString sPropName( "StreamName");
     374           4 :             rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
     375             :         }
     376             : 
     377             : 
     378           8 :         Reference < io::XInputStream > xStream = xEventsStream->getInputStream();
     379           8 :         return ReadThroughComponent( xStream, xModelComponent, rxContext, rPropSet, pFilterName, bEncrypted );
     380             :     }
     381           0 :     catch ( packages::WrongPasswordException& )
     382             :     {
     383           0 :         return ERRCODE_SFX_WRONGPASSWORD;
     384             :     }
     385           0 :     catch( packages::zip::ZipIOException& )
     386             :     {
     387           0 :         return ERRCODE_IO_BROKENPACKAGE;
     388             :     }
     389           2 :     catch ( uno::Exception& )
     390             :     {
     391             :     }
     392             : 
     393           8 :     return ERRCODE_SFX_DOLOADFAILED;
     394             : }
     395             : 
     396             : 
     397             : 
     398          16 : SmXMLImport::SmXMLImport(
     399             :     const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rContext,
     400             :     OUString const & implementationName, SvXMLImportFlags nImportFlags)
     401             : :   SvXMLImport(rContext, implementationName, nImportFlags),
     402          16 :     bSuccess(false)
     403             : {
     404          16 : }
     405             : 
     406             : namespace
     407             : {
     408             :     class theSmXMLImportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSmXMLImportUnoTunnelId> {};
     409             : }
     410             : 
     411          14 : const uno::Sequence< sal_Int8 > & SmXMLImport::getUnoTunnelId() throw()
     412             : {
     413          14 :     return theSmXMLImportUnoTunnelId::get().getSeq();
     414             : }
     415             : 
     416          33 : OUString SAL_CALL SmXMLImport_getImplementationName() throw()
     417             : {
     418          33 :     return OUString( "com.sun.star.comp.Math.XMLImporter" );
     419             : }
     420             : 
     421           4 : uno::Sequence< OUString > SAL_CALL SmXMLImport_getSupportedServiceNames()
     422             :         throw()
     423             : {
     424           4 :     return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
     425             : }
     426             : 
     427           8 : uno::Reference< uno::XInterface > SAL_CALL SmXMLImport_createInstance(
     428             :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     429             :     throw( uno::Exception )
     430             : {
     431           8 :     return static_cast<cppu::OWeakObject*>(new SmXMLImport(comphelper::getComponentContext(rSMgr), SmXMLImport_getImplementationName(), SvXMLImportFlags::ALL));
     432             : }
     433             : 
     434             : 
     435             : 
     436          22 : OUString SAL_CALL SmXMLImportMeta_getImplementationName() throw()
     437             : {
     438          22 :     return OUString( "com.sun.star.comp.Math.XMLOasisMetaImporter" );
     439             : }
     440             : 
     441           2 : uno::Sequence< OUString > SAL_CALL SmXMLImportMeta_getSupportedServiceNames()
     442             : throw()
     443             : {
     444           2 :     return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
     445             : }
     446             : 
     447           3 : uno::Reference< uno::XInterface > SAL_CALL SmXMLImportMeta_createInstance(
     448             :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     449             : throw( uno::Exception )
     450             : {
     451           3 :     return static_cast<cppu::OWeakObject*>(new SmXMLImport( comphelper::getComponentContext(rSMgr), SmXMLImportMeta_getImplementationName(), SvXMLImportFlags::META ));
     452             : }
     453             : 
     454             : 
     455             : 
     456          23 : OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw()
     457             : {
     458          23 :     return OUString( "com.sun.star.comp.Math.XMLOasisSettingsImporter" );
     459             : }
     460             : 
     461           3 : uno::Sequence< OUString > SAL_CALL SmXMLImportSettings_getSupportedServiceNames()
     462             :         throw()
     463             : {
     464           3 :     return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
     465             : }
     466             : 
     467           5 : uno::Reference< uno::XInterface > SAL_CALL SmXMLImportSettings_createInstance(
     468             :     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
     469             :     throw( uno::Exception )
     470             : {
     471           5 :     return static_cast<cppu::OWeakObject*>(new SmXMLImport( comphelper::getComponentContext(rSMgr), SmXMLImportSettings_getImplementationName(), SvXMLImportFlags::SETTINGS ));
     472             : }
     473             : 
     474           7 : sal_Int64 SAL_CALL SmXMLImport::getSomething(
     475             :     const uno::Sequence< sal_Int8 >&rId )
     476             : throw(uno::RuntimeException, std::exception)
     477             : {
     478          14 :     if ( rId.getLength() == 16 &&
     479           7 :         0 == memcmp( getUnoTunnelId().getConstArray(),
     480          14 :         rId.getConstArray(), 16 ) )
     481           7 :         return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
     482             : 
     483           0 :     return SvXMLImport::getSomething( rId );
     484             : }
     485             : 
     486           7 : void SmXMLImport::endDocument()
     487             :     throw(xml::sax::SAXException, uno::RuntimeException, std::exception)
     488             : {
     489             :     //Set the resulted tree into the SmDocShell where it belongs
     490             :     SmNode *pTree;
     491           7 :     if (NULL != (pTree = GetTree()))
     492             :     {
     493           5 :         uno::Reference <frame::XModel> xModel = GetModel();
     494          10 :         uno::Reference <lang::XUnoTunnel> xTunnel;
     495           5 :         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
     496             :         SmModel *pModel = reinterpret_cast<SmModel *>
     497           5 :             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
     498             : 
     499           5 :         if (pModel)
     500             :         {
     501             :             SmDocShell *pDocShell =
     502           5 :                 static_cast<SmDocShell*>(pModel->GetObjectShell());
     503           5 :             pDocShell->SetFormulaTree(pTree);
     504           5 :             if (aText.isEmpty())  //If we picked up no annotation text
     505             :             {
     506             :                 // Get text from imported formula
     507           3 :                 pTree->CreateTextFromNode(aText);
     508           3 :                 aText = comphelper::string::stripEnd(aText, ' ');
     509             :             }
     510             : 
     511             :             // Convert symbol names
     512           5 :             SmParser &rParser = pDocShell->GetParser();
     513           5 :             bool bVal = rParser.IsImportSymbolNames();
     514           5 :             rParser.SetImportSymbolNames( true );
     515           5 :             SmNode *pTmpTree = rParser.Parse( aText );
     516           5 :             aText = rParser.GetText();
     517           5 :             delete pTmpTree;
     518           5 :             rParser.SetImportSymbolNames( bVal );
     519             : 
     520           5 :             pDocShell->SetText( aText );
     521             :         }
     522             :         OSL_ENSURE(pModel,"So there *was* a uno problem after all");
     523             : 
     524          10 :         bSuccess = true;
     525             :     }
     526             : 
     527           7 :     SvXMLImport::endDocument();
     528           7 : }
     529             : 
     530             : 
     531             : 
     532          74 : class SmXMLImportContext: public SvXMLImportContext
     533             : {
     534             : public:
     535          54 :     SmXMLImportContext( SmXMLImport &rImport, sal_uInt16 nPrfx,
     536             :         const OUString& rLName)
     537          54 :         : SvXMLImportContext(rImport, nPrfx, rLName) {}
     538             : 
     539         204 :     SmXMLImport& GetSmImport()
     540             :     {
     541         204 :         return static_cast<SmXMLImport&>(GetImport());
     542             :     }
     543             : 
     544             :     virtual void TCharacters(const OUString & /*rChars*/);
     545             :     virtual void Characters(const OUString &rChars) SAL_OVERRIDE;
     546             :     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 /*nPrefix*/, const OUString& /*rLocalName*/, const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/) SAL_OVERRIDE;
     547             : };
     548             : 
     549           0 : void SmXMLImportContext::TCharacters(const OUString & /*rChars*/)
     550             : {
     551           0 : }
     552             : 
     553          84 : void SmXMLImportContext::Characters(const OUString &rChars)
     554             : {
     555             :     /*
     556             :     Whitespace occurring within the content of token elements is "trimmed"
     557             :     from the ends (i.e. all whitespace at the beginning and end of the
     558             :     content is removed), and "collapsed" internally (i.e. each sequence of
     559             :     1 or more whitespace characters is replaced with one blank character).
     560             :     */
     561             :     //collapsing not done yet!
     562          84 :     const OUString &rChars2 = rChars.trim();
     563          84 :     if (!rChars2.isEmpty())
     564          27 :         TCharacters(rChars2/*.collapse()*/);
     565          84 : }
     566             : 
     567           0 : SvXMLImportContext * SmXMLImportContext::CreateChildContext(sal_uInt16 /*nPrefix*/,
     568             :     const OUString& /*rLocalName*/,
     569             :     const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/)
     570             : {
     571           0 :     return 0;
     572             : }
     573             : 
     574             : 
     575             : 
     576          10 : struct SmXMLContext_Helper
     577             : {
     578             :     sal_Int8 nIsBold;
     579             :     sal_Int8 nIsItalic;
     580             :     double nFontSize;
     581             :     bool bFontNodeNeeded;
     582             :     OUString sFontFamily;
     583             :     OUString sColor;
     584             : 
     585             :     SmXMLImportContext rContext;
     586             : 
     587          10 :     explicit SmXMLContext_Helper(SmXMLImportContext &rImport)
     588             :         : nIsBold( -1 )
     589             :         , nIsItalic( -1 )
     590             :         , nFontSize( 0.0 )
     591             :         , bFontNodeNeeded( false )
     592          10 :         , rContext( rImport )
     593          10 :         {}
     594             : 
     595             :     void RetrieveAttrs(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
     596             :     void ApplyAttrs();
     597             : };
     598             : 
     599          10 : void SmXMLContext_Helper::RetrieveAttrs(const uno::Reference<
     600             :     xml::sax::XAttributeList > & xAttrList )
     601             : {
     602          10 :     sal_Int8 nOldIsBold=nIsBold;
     603          10 :     sal_Int8 nOldIsItalic=nIsItalic;
     604          10 :     double nOldFontSize=nFontSize;
     605          10 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     606          10 :     OUString sOldFontFamily = sFontFamily;
     607          10 :     for (sal_Int16 i=0;i<nAttrCount;i++)
     608             :     {
     609           0 :         OUString sAttrName = xAttrList->getNameByIndex(i);
     610           0 :         OUString aLocalName;
     611           0 :         sal_uInt16 nPrefix = rContext.GetSmImport().GetNamespaceMap().
     612           0 :             GetKeyByAttrName(sAttrName,&aLocalName);
     613           0 :         OUString sValue = xAttrList->getValueByIndex(i);
     614             :         const SvXMLTokenMap &rAttrTokenMap =
     615           0 :             rContext.GetSmImport().GetPresLayoutAttrTokenMap();
     616           0 :         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
     617             :         {
     618             :             case XML_TOK_FONTWEIGHT:
     619           0 :                 nIsBold = sal_Int8(sValue.equals(GetXMLToken(XML_BOLD)));
     620           0 :                 break;
     621             :             case XML_TOK_FONTSTYLE:
     622           0 :                 nIsItalic = sal_Int8(sValue.equals(GetXMLToken(XML_ITALIC)));
     623           0 :                 break;
     624             :             case XML_TOK_FONTSIZE:
     625           0 :                 ::sax::Converter::convertDouble(nFontSize, sValue);
     626           0 :                 rContext.GetSmImport().GetMM100UnitConverter().
     627           0 :                     SetXMLMeasureUnit(util::MeasureUnit::POINT);
     628           0 :                 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
     629             :                 {
     630           0 :                     if (-1 == sValue.indexOf('%'))
     631           0 :                         nFontSize=0.0;
     632             :                     else
     633             :                     {
     634           0 :                         rContext.GetSmImport().GetMM100UnitConverter().
     635           0 :                             SetXMLMeasureUnit(util::MeasureUnit::PERCENT);
     636             :                     }
     637             :                 }
     638           0 :                 break;
     639             :             case XML_TOK_FONTFAMILY:
     640           0 :                 sFontFamily = sValue;
     641           0 :                 break;
     642             :             case XML_TOK_COLOR:
     643           0 :                 sColor = sValue;
     644           0 :                 break;
     645             :             case XML_TOK_MATHCOLOR:
     646           0 :                 sColor = sValue;
     647           0 :                 break;
     648             :             default:
     649           0 :                 break;
     650             :         }
     651           0 :     }
     652             : 
     653          40 :     if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
     654          20 :         (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
     655          20 :         || !sColor.isEmpty())
     656           0 :         bFontNodeNeeded=true;
     657             :     else
     658          10 :         bFontNodeNeeded=false;
     659          10 : }
     660             : 
     661           0 : void SmXMLContext_Helper::ApplyAttrs()
     662             : {
     663           0 :     SmNodeStack &rNodeStack = rContext.GetSmImport().GetNodeStack();
     664             : 
     665           0 :     if (bFontNodeNeeded)
     666             :     {
     667           0 :         SmToken aToken;
     668           0 :         aToken.cMathChar = '\0';
     669           0 :         aToken.nLevel = 5;
     670             : 
     671           0 :         if (nIsBold != -1)
     672             :         {
     673           0 :             if (nIsBold)
     674           0 :                 aToken.eType = TBOLD;
     675             :             else
     676           0 :                 aToken.eType = TNBOLD;
     677             :             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
     678           0 :                 (new SmFontNode(aToken));
     679           0 :             pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
     680           0 :             rNodeStack.push_front(pFontNode);
     681             :         }
     682           0 :         if (nIsItalic != -1)
     683             :         {
     684           0 :             if (nIsItalic)
     685           0 :                 aToken.eType = TITALIC;
     686             :             else
     687           0 :                 aToken.eType = TNITALIC;
     688             :             SmStructureNode *pFontNode = static_cast<SmStructureNode *>
     689           0 :                 (new SmFontNode(aToken));
     690           0 :             pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
     691           0 :             rNodeStack.push_front(pFontNode);
     692             :         }
     693           0 :         if (nFontSize != 0.0)
     694             :         {
     695           0 :             aToken.eType = TSIZE;
     696           0 :             SmFontNode *pFontNode = new SmFontNode(aToken);
     697             : 
     698           0 :             if (util::MeasureUnit::PERCENT == rContext.GetSmImport()
     699           0 :                     .GetMM100UnitConverter().GetXMLMeasureUnit())
     700             :             {
     701           0 :                 if (nFontSize < 100.00)
     702             :                     pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
     703           0 :                         FontSizeType::DIVIDE);
     704             :                 else
     705             :                     pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
     706           0 :                         FontSizeType::MULTIPLY);
     707             :             }
     708             :             else
     709           0 :                 pFontNode->SetSizeParameter(Fraction(nFontSize),FontSizeType::ABSOLUT);
     710             : 
     711           0 :             pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
     712           0 :             rNodeStack.push_front(pFontNode);
     713             :         }
     714           0 :         if (!sFontFamily.isEmpty())
     715             :         {
     716           0 :             if (sFontFamily.equalsIgnoreAsciiCase(GetXMLToken(XML_FIXED)))
     717           0 :                 aToken.eType = TFIXED;
     718           0 :             else if (sFontFamily.equalsIgnoreAsciiCase("sans"))
     719           0 :                 aToken.eType = TSANS;
     720           0 :             else if (sFontFamily.equalsIgnoreAsciiCase("serif"))
     721           0 :                 aToken.eType = TSERIF;
     722             :             else //Just give up, we need to extend our font mechanism to be
     723             :                 //more general
     724           0 :                 return;
     725             : 
     726           0 :             aToken.aText = sFontFamily;
     727           0 :             SmFontNode *pFontNode = new SmFontNode(aToken);
     728           0 :             pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
     729           0 :             rNodeStack.push_front(pFontNode);
     730             :         }
     731           0 :         if (!sColor.isEmpty())
     732             :         {
     733             :             //Again we can only handle a small set of colours in
     734             :             //StarMath for now.
     735             :             const SvXMLTokenMap& rTokenMap =
     736           0 :                 rContext.GetSmImport().GetColorTokenMap();
     737           0 :             sal_uInt16 tok = rTokenMap.Get(XML_NAMESPACE_MATH, sColor);
     738           0 :             if (tok != XML_TOK_UNKNOWN)
     739             :             {
     740           0 :                 aToken.eType = static_cast<SmTokenType>(tok);
     741           0 :                 SmFontNode *pFontNode = new SmFontNode(aToken);
     742           0 :                 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
     743           0 :                 rNodeStack.push_front(pFontNode);
     744             :             }
     745           0 :         }
     746             : 
     747             :     }
     748             : }
     749             : 
     750             : 
     751             : 
     752          30 : class SmXMLDocContext_Impl : public SmXMLImportContext
     753             : {
     754             : public:
     755          25 :     SmXMLDocContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
     756             :         const OUString& rLName)
     757          25 :         : SmXMLImportContext(rImport,nPrfx,rLName) {}
     758             : 
     759             :     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
     760             : 
     761             :     void EndElement() SAL_OVERRIDE;
     762             : };
     763             : 
     764             : 
     765             : 
     766             : /*avert thy gaze from the proginator*/
     767          25 : class SmXMLRowContext_Impl : public SmXMLDocContext_Impl
     768             : {
     769             : protected:
     770             :     size_t nElementCount;
     771             : 
     772             : public:
     773          20 :     SmXMLRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     774             :         const OUString& rLName)
     775          20 :         : SmXMLDocContext_Impl(rImport,nPrefix,rLName)
     776          20 :         { nElementCount = GetSmImport().GetNodeStack().size(); }
     777             : 
     778             :     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
     779             : 
     780             :     SvXMLImportContext *StrictCreateChildContext(sal_uInt16 nPrefix,
     781             :         const OUString& rLocalName,
     782             :         const uno::Reference< xml::sax::XAttributeList > &xAttrList);
     783             : 
     784             :     void EndElement() SAL_OVERRIDE;
     785             : };
     786             : 
     787             : 
     788             : 
     789           0 : class SmXMLEncloseContext_Impl : public SmXMLRowContext_Impl
     790             : {
     791             : public:
     792             :     // TODO/LATER: convert <menclose notation="horizontalstrike"> into
     793             :     // "overstrike{}" and extend the Math syntax to support more notations
     794           0 :     SmXMLEncloseContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     795             :         const OUString& rLName)
     796           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     797             : 
     798             :     void EndElement() SAL_OVERRIDE;
     799             : };
     800             : 
     801           0 : void SmXMLEncloseContext_Impl::EndElement()
     802             : {
     803             :     /*
     804             :     <menclose> accepts any number of arguments; if this number is not 1, its
     805             :     contents are treated as a single "inferred <mrow>" containing its
     806             :     arguments
     807             :     */
     808           0 :     if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
     809           0 :         SmXMLRowContext_Impl::EndElement();
     810           0 : }
     811             : 
     812             : 
     813             : 
     814           0 : class SmXMLFracContext_Impl : public SmXMLRowContext_Impl
     815             : {
     816             : public:
     817             :     // TODO/LATER: convert <mfrac bevelled="true"> into "wideslash{}{}"
     818           0 :     SmXMLFracContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     819             :         const OUString& rLName)
     820           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     821             : 
     822             :     void EndElement() SAL_OVERRIDE;
     823             : };
     824             : 
     825             : 
     826             : 
     827           0 : class SmXMLSqrtContext_Impl : public SmXMLRowContext_Impl
     828             : {
     829             : public:
     830           0 :     SmXMLSqrtContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     831             :         const OUString& rLName)
     832           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     833             : 
     834             :     void EndElement() SAL_OVERRIDE;
     835             : };
     836             : 
     837             : 
     838             : 
     839           0 : class SmXMLRootContext_Impl : public SmXMLRowContext_Impl
     840             : {
     841             : public:
     842           0 :     SmXMLRootContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     843             :         const OUString& rLName)
     844           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     845             : 
     846             :     void EndElement() SAL_OVERRIDE;
     847             : };
     848             : 
     849             : 
     850             : 
     851           0 : class SmXMLStyleContext_Impl : public SmXMLRowContext_Impl
     852             : {
     853             : protected:
     854             :     SmXMLContext_Helper aStyleHelper;
     855             : 
     856             : public:
     857             :     /*Right now the style tag is completely ignored*/
     858           0 :     SmXMLStyleContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     859             :         const OUString& rLName) : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
     860           0 :         aStyleHelper(*this) {}
     861             : 
     862             :     void EndElement() SAL_OVERRIDE;
     863             :     void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
     864             : };
     865             : 
     866           0 : void SmXMLStyleContext_Impl::StartElement(const uno::Reference<
     867             :     xml::sax::XAttributeList > & xAttrList )
     868             : {
     869           0 :     aStyleHelper.RetrieveAttrs(xAttrList);
     870           0 : }
     871             : 
     872             : 
     873           0 : void SmXMLStyleContext_Impl::EndElement()
     874             : {
     875             :     /*
     876             :     <mstyle> accepts any number of arguments; if this number is not 1, its
     877             :     contents are treated as a single "inferred <mrow>" containing its
     878             :     arguments
     879             :     */
     880           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
     881           0 :     if (rNodeStack.size() - nElementCount > 1)
     882           0 :         SmXMLRowContext_Impl::EndElement();
     883           0 :     aStyleHelper.ApplyAttrs();
     884           0 : }
     885             : 
     886             : 
     887             : 
     888           0 : class SmXMLPaddedContext_Impl : public SmXMLRowContext_Impl
     889             : {
     890             : public:
     891             :     /*Right now the style tag is completely ignored*/
     892           0 :     SmXMLPaddedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     893             :         const OUString& rLName)
     894           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     895             : 
     896             :     void EndElement() SAL_OVERRIDE;
     897             : };
     898             : 
     899           0 : void SmXMLPaddedContext_Impl::EndElement()
     900             : {
     901             :     /*
     902             :     <mpadded> accepts any number of arguments; if this number is not 1, its
     903             :     contents are treated as a single "inferred <mrow>" containing its
     904             :     arguments
     905             :     */
     906           0 :     if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
     907           0 :         SmXMLRowContext_Impl::EndElement();
     908           0 : }
     909             : 
     910             : 
     911             : 
     912           0 : class SmXMLPhantomContext_Impl : public SmXMLRowContext_Impl
     913             : {
     914             : public:
     915             :     /*Right now the style tag is completely ignored*/
     916           0 :     SmXMLPhantomContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     917             :         const OUString& rLName)
     918           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
     919             : 
     920             :     void EndElement() SAL_OVERRIDE;
     921             : };
     922             : 
     923           0 : void SmXMLPhantomContext_Impl::EndElement()
     924             : {
     925             :     /*
     926             :     <mphantom> accepts any number of arguments; if this number is not 1, its
     927             :     contents are treated as a single "inferred <mrow>" containing its
     928             :     arguments
     929             :     */
     930           0 :     if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
     931           0 :         SmXMLRowContext_Impl::EndElement();
     932             : 
     933           0 :     SmToken aToken;
     934           0 :     aToken.cMathChar = '\0';
     935           0 :     aToken.nLevel = 5;
     936           0 :     aToken.eType = TPHANTOM;
     937             : 
     938             :     SmStructureNode *pPhantom = static_cast<SmStructureNode *>
     939           0 :         (new SmFontNode(aToken));
     940           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
     941           0 :     pPhantom->SetSubNodes(0,popOrZero(rNodeStack));
     942           0 :     rNodeStack.push_front(pPhantom);
     943           0 : }
     944             : 
     945             : 
     946             : 
     947           4 : class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
     948             : {
     949             : protected:
     950             :     sal_Unicode cBegin;
     951             :     sal_Unicode cEnd;
     952             : 
     953             : public:
     954           2 :     SmXMLFencedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
     955             :         const OUString& rLName)
     956             :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
     957           2 :         cBegin('('), cEnd(')') {}
     958             : 
     959             :     void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE;
     960             :     void EndElement() SAL_OVERRIDE;
     961             : };
     962             : 
     963             : 
     964           2 : void SmXMLFencedContext_Impl::StartElement(const uno::Reference<
     965             :     xml::sax::XAttributeList > & xAttrList )
     966             : {
     967           2 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     968           2 :     for (sal_Int16 i=0;i<nAttrCount;i++)
     969             :     {
     970           0 :         OUString sAttrName = xAttrList->getNameByIndex(i);
     971           0 :         OUString aLocalName;
     972           0 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
     973           0 :             GetKeyByAttrName(sAttrName,&aLocalName);
     974           0 :         OUString sValue = xAttrList->getValueByIndex(i);
     975             :         const SvXMLTokenMap &rAttrTokenMap =
     976           0 :             GetSmImport().GetFencedAttrTokenMap();
     977           0 :         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
     978             :         {
     979             :             //temp, starmath cannot handle multichar brackets (I think)
     980             :             case XML_TOK_OPEN:
     981           0 :                 cBegin = sValue[0];
     982           0 :                 break;
     983             :             case XML_TOK_CLOSE:
     984           0 :                 cEnd = sValue[0];
     985           0 :                 break;
     986             :             default:
     987             :                 /*Go to superclass*/
     988           0 :                 break;
     989             :         }
     990           0 :     }
     991           2 : }
     992             : 
     993             : 
     994           2 : void SmXMLFencedContext_Impl::EndElement()
     995             : {
     996           2 :     SmToken aToken;
     997           2 :     aToken.cMathChar = '\0';
     998           2 :     aToken.aText = ",";
     999           2 :     aToken.eType = TLEFT;
    1000           2 :     aToken.nLevel = 5;
    1001             : 
    1002           2 :     aToken.eType = TLPARENT;
    1003           2 :     aToken.cMathChar = cBegin;
    1004           2 :     SmStructureNode *pSNode = new SmBraceNode(aToken);
    1005           2 :     SmNode *pLeft = new SmMathSymbolNode(aToken);
    1006             : 
    1007           2 :     aToken.cMathChar = cEnd;
    1008           2 :     aToken.eType = TRPARENT;
    1009           2 :     SmNode *pRight = new SmMathSymbolNode(aToken);
    1010             : 
    1011           4 :     SmNodeArray aRelationArray;
    1012           2 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1013             : 
    1014           2 :     aToken.cMathChar = '\0';
    1015           2 :     aToken.aText = ",";
    1016           2 :     aToken.eType = TIDENT;
    1017             : 
    1018           2 :     auto i = rNodeStack.size() - nElementCount;
    1019           2 :     if (rNodeStack.size() - nElementCount > 1)
    1020           0 :         i += rNodeStack.size() - 1 - nElementCount;
    1021           2 :     aRelationArray.resize(i);
    1022           6 :     while (rNodeStack.size() > nElementCount)
    1023             :     {
    1024           2 :         auto pNode = rNodeStack.pop_front();
    1025           2 :         aRelationArray[--i] = pNode.release();
    1026           2 :         if (i > 1 && rNodeStack.size() > 1)
    1027           0 :             aRelationArray[--i] = new SmGlyphSpecialNode(aToken);
    1028           2 :     }
    1029             : 
    1030           4 :     SmToken aDummy;
    1031           2 :     SmStructureNode *pBody = new SmExpressionNode(aDummy);
    1032           2 :     pBody->SetSubNodes(aRelationArray);
    1033             : 
    1034             : 
    1035           2 :     pSNode->SetSubNodes(pLeft,pBody,pRight);
    1036           2 :     pSNode->SetScaleMode(SCALE_HEIGHT);
    1037           4 :     GetSmImport().GetNodeStack().push_front(pSNode);
    1038           2 : }
    1039             : 
    1040             : 
    1041             : 
    1042             : 
    1043           0 : class SmXMLErrorContext_Impl : public SmXMLRowContext_Impl
    1044             : {
    1045             : public:
    1046           0 :     SmXMLErrorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1047             :         const OUString& rLName)
    1048           0 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
    1049             : 
    1050             :     void EndElement() SAL_OVERRIDE;
    1051             : };
    1052             : 
    1053           0 : void SmXMLErrorContext_Impl::EndElement()
    1054             : {
    1055             :     /*Right now the error tag is completely ignored, what
    1056             :      can I do with it in starmath, ?, maybe we need a
    1057             :      report window ourselves, do a test for validity of
    1058             :      the xml input, use merrors, and then generate
    1059             :      the markup inside the merror with a big red colour
    1060             :      of something. For now just throw them all away.
    1061             :      */
    1062           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1063           0 :     while (rNodeStack.size() > nElementCount)
    1064             :     {
    1065           0 :         rNodeStack.pop_front();
    1066             :     }
    1067           0 : }
    1068             : 
    1069             : 
    1070             : 
    1071          30 : class SmXMLNumberContext_Impl : public SmXMLImportContext
    1072             : {
    1073             : protected:
    1074             :     SmToken aToken;
    1075             : 
    1076             : public:
    1077          15 :     SmXMLNumberContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1078             :         const OUString& rLName)
    1079          15 :         : SmXMLImportContext(rImport,nPrefix,rLName)
    1080             :     {
    1081          15 :         aToken.cMathChar = '\0';
    1082          15 :         aToken.nLevel = 5;
    1083          15 :         aToken.eType = TNUMBER;
    1084          15 :     }
    1085             : 
    1086             :     virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
    1087             : 
    1088             :     void EndElement() SAL_OVERRIDE;
    1089             : };
    1090             : 
    1091          15 : void SmXMLNumberContext_Impl::TCharacters(const OUString &rChars)
    1092             : {
    1093          15 :     aToken.aText = rChars;
    1094          15 : }
    1095             : 
    1096          15 : void SmXMLNumberContext_Impl::EndElement()
    1097             : {
    1098          15 :     GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_NUMBER));
    1099          15 : }
    1100             : 
    1101             : 
    1102             : 
    1103           4 : class SmXMLAnnotationContext_Impl : public SmXMLImportContext
    1104             : {
    1105             :     bool bIsStarMath;
    1106             : 
    1107             : public:
    1108           2 :     SmXMLAnnotationContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1109             :         const OUString& rLName)
    1110           2 :         : SmXMLImportContext(rImport,nPrefix,rLName), bIsStarMath(false) {}
    1111             : 
    1112             :     virtual void Characters(const OUString &rChars) SAL_OVERRIDE;
    1113             : 
    1114             :     void StartElement(const uno::Reference<xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE;
    1115             : };
    1116             : 
    1117           2 : void SmXMLAnnotationContext_Impl::StartElement(const uno::Reference<
    1118             :     xml::sax::XAttributeList > & xAttrList )
    1119             : {
    1120           2 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1121           4 :     for (sal_Int16 i=0;i<nAttrCount;i++)
    1122             :     {
    1123           2 :         OUString sAttrName = xAttrList->getNameByIndex(i);
    1124           4 :         OUString aLocalName;
    1125           2 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
    1126           2 :             GetKeyByAttrName(sAttrName,&aLocalName);
    1127             : 
    1128           4 :         OUString sValue = xAttrList->getValueByIndex(i);
    1129             :         const SvXMLTokenMap &rAttrTokenMap =
    1130           2 :             GetSmImport().GetAnnotationAttrTokenMap();
    1131           2 :         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
    1132             :         {
    1133             :             case XML_TOK_ENCODING:
    1134           2 :                 bIsStarMath= sValue == "StarMath 5.0";
    1135           2 :                 break;
    1136             :             default:
    1137           0 :                 break;
    1138             :         }
    1139           2 :     }
    1140           2 : }
    1141             : 
    1142           2 : void SmXMLAnnotationContext_Impl::Characters(const OUString &rChars)
    1143             : {
    1144           2 :     if (bIsStarMath)
    1145           2 :         GetSmImport().SetText( GetSmImport().GetText() + rChars );
    1146           2 : }
    1147             : 
    1148             : 
    1149             : 
    1150           0 : class SmXMLTextContext_Impl : public SmXMLImportContext
    1151             : {
    1152             : protected:
    1153             :     SmToken aToken;
    1154             : 
    1155             : public:
    1156           0 :     SmXMLTextContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1157             :         const OUString& rLName)
    1158           0 :         : SmXMLImportContext(rImport,nPrefix,rLName)
    1159             :     {
    1160           0 :         aToken.cMathChar = '\0';
    1161           0 :         aToken.nLevel = 5;
    1162           0 :         aToken.eType = TTEXT;
    1163           0 :     }
    1164             : 
    1165             :     virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
    1166             : 
    1167             :     void EndElement() SAL_OVERRIDE;
    1168             : };
    1169             : 
    1170           0 : void SmXMLTextContext_Impl::TCharacters(const OUString &rChars)
    1171             : {
    1172           0 :     aToken.aText = rChars;
    1173           0 : }
    1174             : 
    1175           0 : void SmXMLTextContext_Impl::EndElement()
    1176             : {
    1177           0 :     GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_TEXT));
    1178           0 : }
    1179             : 
    1180             : 
    1181             : 
    1182           0 : class SmXMLStringContext_Impl : public SmXMLImportContext
    1183             : {
    1184             : protected:
    1185             :     SmToken aToken;
    1186             : 
    1187             : public:
    1188           0 :     SmXMLStringContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1189             :         const OUString& rLName)
    1190           0 :         : SmXMLImportContext(rImport,nPrefix,rLName)
    1191             :     {
    1192           0 :         aToken.cMathChar = '\0';
    1193           0 :         aToken.nLevel = 5;
    1194           0 :         aToken.eType = TTEXT;
    1195           0 :     }
    1196             : 
    1197             :     virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
    1198             : 
    1199             :     void EndElement() SAL_OVERRIDE;
    1200             : };
    1201             : 
    1202           0 : void SmXMLStringContext_Impl::TCharacters(const OUString &rChars)
    1203             : {
    1204             :     /*
    1205             :     The content of <ms> elements should be rendered with visible "escaping" of
    1206             :     certain characters in the content, including at least "double quote"
    1207             :     itself, and preferably whitespace other than individual blanks. The intent
    1208             :     is for the viewer to see that the expression is a string literal, and to
    1209             :     see exactly which characters form its content. For example, <ms>double
    1210             :     quote is "</ms> might be rendered as "double quote is \"".
    1211             : 
    1212             :     Obviously this isn't fully done here.
    1213             :     */
    1214           0 :     aToken.aText = "\"" + rChars + "\"";
    1215           0 : }
    1216             : 
    1217           0 : void SmXMLStringContext_Impl::EndElement()
    1218             : {
    1219           0 :     GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_FIXED));
    1220           0 : }
    1221             : 
    1222             : 
    1223             : 
    1224          20 : class SmXMLIdentifierContext_Impl : public SmXMLImportContext
    1225             : {
    1226             : protected:
    1227             :     SmXMLContext_Helper aStyleHelper;
    1228             :     SmToken aToken;
    1229             : 
    1230             : public:
    1231          10 :     SmXMLIdentifierContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1232             :         const OUString& rLName)
    1233          10 :         : SmXMLImportContext(rImport,nPrefix,rLName),aStyleHelper(*this)
    1234             :     {
    1235          10 :         aToken.cMathChar = '\0';
    1236          10 :         aToken.nLevel = 5;
    1237          10 :         aToken.eType = TIDENT;
    1238          10 :     }
    1239             : 
    1240             :     void TCharacters(const OUString &rChars) SAL_OVERRIDE;
    1241          10 :     void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE
    1242             :     {
    1243          10 :         aStyleHelper.RetrieveAttrs(xAttrList);
    1244          10 :     };
    1245             :     void EndElement() SAL_OVERRIDE;
    1246             : };
    1247             : 
    1248          10 : void SmXMLIdentifierContext_Impl::EndElement()
    1249             : {
    1250          10 :     SmTextNode *pNode = 0;
    1251             :     //we will handle identifier italic/normal here instead of with a standalone
    1252             :     //font node
    1253          30 :     if (((aStyleHelper.nIsItalic == -1) && (aToken.aText.getLength() > 1))
    1254          20 :         || ((aStyleHelper.nIsItalic == 0) && (aToken.aText.getLength() == 1)))
    1255             :     {
    1256           0 :         pNode = new SmTextNode(aToken,FNT_FUNCTION);
    1257           0 :         pNode->GetFont().SetItalic(ITALIC_NONE);
    1258           0 :         aStyleHelper.nIsItalic = -1;
    1259             :     }
    1260             :     else
    1261          10 :         pNode = new SmTextNode(aToken,FNT_VARIABLE);
    1262          10 :     if (aStyleHelper.bFontNodeNeeded && aStyleHelper.nIsItalic != -1)
    1263             :     {
    1264           0 :         if (aStyleHelper.nIsItalic)
    1265           0 :             pNode->GetFont().SetItalic(ITALIC_NORMAL);
    1266             :         else
    1267           0 :             pNode->GetFont().SetItalic(ITALIC_NONE);
    1268             :     }
    1269             : 
    1270          40 :     if ((-1!=aStyleHelper.nIsBold) || (0.0!=aStyleHelper.nFontSize) ||
    1271          30 :         (!aStyleHelper.sFontFamily.isEmpty()) ||
    1272          10 :         !aStyleHelper.sColor.isEmpty())
    1273           0 :         aStyleHelper.bFontNodeNeeded=true;
    1274             :     else
    1275          10 :         aStyleHelper.bFontNodeNeeded=false;
    1276          10 :     if (aStyleHelper.bFontNodeNeeded)
    1277           0 :         aStyleHelper.ApplyAttrs();
    1278          10 :     GetSmImport().GetNodeStack().push_front(pNode);
    1279          10 : }
    1280             : 
    1281          10 : void SmXMLIdentifierContext_Impl::TCharacters(const OUString &rChars)
    1282             : {
    1283          10 :     aToken.aText = rChars;
    1284          10 : }
    1285             : 
    1286             : 
    1287             : 
    1288           4 : class SmXMLOperatorContext_Impl : public SmXMLImportContext
    1289             : {
    1290             :     bool bIsStretchy;
    1291             : 
    1292             : protected:
    1293             :     SmToken aToken;
    1294             : 
    1295             : public:
    1296           2 :     SmXMLOperatorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1297             :         const OUString& rLName)
    1298           2 :         : SmXMLImportContext(rImport,nPrefix,rLName), bIsStretchy(false)
    1299             :     {
    1300           2 :         aToken.eType = TSPECIAL;
    1301           2 :         aToken.nLevel = 5;
    1302           2 :     }
    1303             : 
    1304             :     void TCharacters(const OUString &rChars) SAL_OVERRIDE;
    1305             :     void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
    1306             :     void EndElement() SAL_OVERRIDE;
    1307             : };
    1308             : 
    1309           2 : void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
    1310             : {
    1311           2 :     aToken.cMathChar = rChars[0];
    1312           2 : }
    1313             : 
    1314           2 : void SmXMLOperatorContext_Impl::EndElement()
    1315             : {
    1316           2 :     SmMathSymbolNode *pNode = new SmMathSymbolNode(aToken);
    1317             :     //For stretchy scaling the scaling must be retrieved from this node
    1318             :     //and applied to the expression itself so as to get the expression
    1319             :     //to scale the operator to the height of the expression itself
    1320           2 :     if (bIsStretchy)
    1321           0 :         pNode->SetScaleMode(SCALE_HEIGHT);
    1322           2 :     GetSmImport().GetNodeStack().push_front(pNode);
    1323           2 : }
    1324             : 
    1325             : 
    1326             : 
    1327           2 : void SmXMLOperatorContext_Impl::StartElement(const uno::Reference<
    1328             :     xml::sax::XAttributeList > & xAttrList )
    1329             : {
    1330           2 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1331           2 :     for (sal_Int16 i=0;i<nAttrCount;i++)
    1332             :     {
    1333           0 :         OUString sAttrName = xAttrList->getNameByIndex(i);
    1334           0 :         OUString aLocalName;
    1335           0 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
    1336           0 :             GetKeyByAttrName(sAttrName,&aLocalName);
    1337             : 
    1338           0 :         OUString sValue = xAttrList->getValueByIndex(i);
    1339             :         const SvXMLTokenMap &rAttrTokenMap =
    1340           0 :             GetSmImport().GetOperatorAttrTokenMap();
    1341           0 :         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
    1342             :         {
    1343             :             case XML_TOK_STRETCHY:
    1344             :                 bIsStretchy = sValue.equals(
    1345           0 :                     GetXMLToken(XML_TRUE));
    1346           0 :                 break;
    1347             :             default:
    1348           0 :                 break;
    1349             :         }
    1350           0 :     }
    1351           2 : }
    1352             : 
    1353             : 
    1354             : 
    1355             : 
    1356           0 : class SmXMLSpaceContext_Impl : public SmXMLImportContext
    1357             : {
    1358             : public:
    1359           0 :     SmXMLSpaceContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1360             :         const OUString& rLName)
    1361           0 :         : SmXMLImportContext(rImport,nPrefix,rLName) {}
    1362             : 
    1363             :     void StartElement(const uno::Reference< xml::sax::XAttributeList >& xAttrList ) SAL_OVERRIDE;
    1364             : };
    1365             : 
    1366           0 : void SmXMLSpaceContext_Impl::StartElement(
    1367             :     const uno::Reference<xml::sax::XAttributeList > & /*xAttrList*/ )
    1368             : {
    1369             :     // There is not any syntax in Math to specify blank nodes of arbitrary
    1370             :     // size. Hence we always interpret an <mspace> as a large gap "~".
    1371           0 :     SmToken aToken;
    1372           0 :     aToken.cMathChar = '\0';
    1373           0 :     aToken.eType = TBLANK;
    1374           0 :     aToken.nLevel = 5;
    1375           0 :     SmBlankNode *pBlank = new SmBlankNode(aToken);
    1376           0 :     pBlank->IncreaseBy(aToken);
    1377           0 :     GetSmImport().GetNodeStack().push_front(pBlank);
    1378           0 : }
    1379             : 
    1380             : 
    1381             : 
    1382           2 : class SmXMLSubContext_Impl : public SmXMLRowContext_Impl
    1383             : {
    1384             : protected:
    1385             :     void GenericEndElement(SmTokenType eType,SmSubSup aSubSup);
    1386             : 
    1387             : public:
    1388           2 :     SmXMLSubContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1389             :         const OUString& rLName)
    1390           2 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
    1391             : 
    1392           0 :     void EndElement() SAL_OVERRIDE
    1393             :     {
    1394           0 :         GenericEndElement(TRSUB,RSUB);
    1395           0 :     }
    1396             : };
    1397             : 
    1398             : 
    1399           2 : void SmXMLSubContext_Impl::GenericEndElement(SmTokenType eType, SmSubSup eSubSup)
    1400             : {
    1401             :     /*The <msub> element requires exactly 2 arguments.*/
    1402           2 :     const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
    1403             :     OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
    1404           2 :     if (!bNodeCheck)
    1405           2 :         return;
    1406             : 
    1407           2 :     SmToken aToken;
    1408           2 :     aToken.cMathChar = '\0';
    1409           2 :     aToken.eType = eType;
    1410           2 :     SmSubSupNode *pNode = new SmSubSupNode(aToken);
    1411           2 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1412             : 
    1413             :     // initialize subnodes array
    1414           4 :     SmNodeArray  aSubNodes;
    1415           2 :     aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
    1416          14 :     for (size_t i = 1;  i < aSubNodes.size();  i++)
    1417          12 :         aSubNodes[i] = NULL;
    1418             : 
    1419           2 :     aSubNodes[eSubSup+1] = popOrZero(rNodeStack);
    1420           2 :     aSubNodes[0] = popOrZero(rNodeStack);
    1421           2 :     pNode->SetSubNodes(aSubNodes);
    1422           4 :     rNodeStack.push_front(pNode);
    1423             : }
    1424             : 
    1425             : 
    1426             : 
    1427           4 : class SmXMLSupContext_Impl : public SmXMLSubContext_Impl
    1428             : {
    1429             : public:
    1430           2 :     SmXMLSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1431             :         const OUString& rLName)
    1432           2 :         : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
    1433             : 
    1434           2 :     void EndElement() SAL_OVERRIDE
    1435             :     {
    1436           2 :         GenericEndElement(TRSUP,RSUP);
    1437           2 :     }
    1438             : };
    1439             : 
    1440             : 
    1441             : 
    1442           8 : class SmXMLSubSupContext_Impl : public SmXMLRowContext_Impl
    1443             : {
    1444             : protected:
    1445             :     void GenericEndElement(SmTokenType eType, SmSubSup aSub,SmSubSup aSup);
    1446             : 
    1447             : public:
    1448           4 :     SmXMLSubSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1449             :         const OUString& rLName)
    1450           4 :         : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
    1451             : 
    1452           4 :     void EndElement() SAL_OVERRIDE
    1453             :     {
    1454           4 :         GenericEndElement(TRSUB,RSUB,RSUP);
    1455           4 :     }
    1456             : };
    1457             : 
    1458           4 : void SmXMLSubSupContext_Impl::GenericEndElement(SmTokenType eType,
    1459             :         SmSubSup aSub,SmSubSup aSup)
    1460             : {
    1461             :     /*The <msub> element requires exactly 3 arguments.*/
    1462           4 :     const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 3;
    1463             :     OSL_ENSURE( bNodeCheck, "SubSup has not three arguments" );
    1464           4 :     if (!bNodeCheck)
    1465           4 :         return;
    1466             : 
    1467           4 :     SmToken aToken;
    1468           4 :     aToken.cMathChar = '\0';
    1469           4 :     aToken.eType = eType;
    1470           4 :     SmSubSupNode *pNode = new SmSubSupNode(aToken);
    1471           4 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1472             : 
    1473             :     // initialize subnodes array
    1474           8 :     SmNodeArray  aSubNodes;
    1475           4 :     aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
    1476          28 :     for (size_t i = 1;  i < aSubNodes.size();  i++)
    1477          24 :         aSubNodes[i] = NULL;
    1478             : 
    1479           4 :     aSubNodes[aSup+1] = popOrZero(rNodeStack);
    1480           4 :     aSubNodes[aSub+1] = popOrZero(rNodeStack);
    1481           4 :     aSubNodes[0] =  popOrZero(rNodeStack);
    1482           4 :     pNode->SetSubNodes(aSubNodes);
    1483           8 :     rNodeStack.push_front(pNode);
    1484             : }
    1485             : 
    1486             : 
    1487             : 
    1488           0 : class SmXMLUnderContext_Impl : public SmXMLSubContext_Impl
    1489             : {
    1490             : protected:
    1491             :     sal_Int16 nAttrCount;
    1492             : 
    1493             : public:
    1494           0 :     SmXMLUnderContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1495             :                            const OUString& rLName)
    1496             :         : SmXMLSubContext_Impl(rImport,nPrefix,rLName)
    1497           0 :         , nAttrCount( 0 )
    1498           0 :         {}
    1499             : 
    1500             :     void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
    1501             :     void EndElement() SAL_OVERRIDE;
    1502             :     void HandleAccent();
    1503             : };
    1504             : 
    1505           0 : void SmXMLUnderContext_Impl::StartElement(const uno::Reference<
    1506             :     xml::sax::XAttributeList > & xAttrList )
    1507             : {
    1508           0 :     nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1509           0 : }
    1510             : 
    1511           0 : void SmXMLUnderContext_Impl::HandleAccent()
    1512             : {
    1513           0 :     const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
    1514             :     OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
    1515           0 :     if (!bNodeCheck)
    1516           0 :         return;
    1517             : 
    1518             :     /*Just one special case for the underline thing*/
    1519           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1520           0 :     SmNode *pTest = popOrZero(rNodeStack);
    1521           0 :     SmToken aToken;
    1522           0 :     aToken.cMathChar = '\0';
    1523           0 :     aToken.eType = TUNDERLINE;
    1524             : 
    1525             : 
    1526           0 :     SmNodeArray aSubNodes;
    1527           0 :     aSubNodes.resize(2);
    1528             : 
    1529           0 :     SmStructureNode *pNode = new SmAttributNode(aToken);
    1530           0 :     if ((pTest->GetToken().cMathChar & 0x0FFF) == 0x0332)
    1531             :     {
    1532           0 :         aSubNodes[0] = new SmRectangleNode(aToken);
    1533           0 :         delete pTest;
    1534             :     }
    1535             :     else
    1536           0 :         aSubNodes[0] = pTest;
    1537             : 
    1538           0 :     aSubNodes[1] = popOrZero(rNodeStack);
    1539           0 :     pNode->SetSubNodes(aSubNodes);
    1540           0 :     pNode->SetScaleMode(SCALE_WIDTH);
    1541           0 :     rNodeStack.push_front(pNode);
    1542             : }
    1543             : 
    1544             : 
    1545           0 : void SmXMLUnderContext_Impl::EndElement()
    1546             : {
    1547           0 :     if (!nAttrCount)
    1548           0 :         GenericEndElement(TCSUB,CSUB);
    1549             :     else
    1550           0 :         HandleAccent();
    1551           0 : }
    1552             : 
    1553             : 
    1554             : 
    1555           0 : class SmXMLOverContext_Impl : public SmXMLSubContext_Impl
    1556             : {
    1557             : protected:
    1558             :     sal_Int16 nAttrCount;
    1559             : 
    1560             : public:
    1561           0 :     SmXMLOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1562             :         const OUString& rLName)
    1563           0 :         : SmXMLSubContext_Impl(rImport,nPrefix,rLName), nAttrCount(0) {}
    1564             : 
    1565             :     void EndElement() SAL_OVERRIDE;
    1566             :     void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
    1567             :     void HandleAccent();
    1568             : };
    1569             : 
    1570             : 
    1571           0 : void SmXMLOverContext_Impl::StartElement(const uno::Reference<
    1572             :     xml::sax::XAttributeList > & xAttrList )
    1573             : {
    1574           0 :     nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    1575           0 : }
    1576             : 
    1577             : 
    1578           0 : void SmXMLOverContext_Impl::EndElement()
    1579             : {
    1580           0 :     if (!nAttrCount)
    1581           0 :         GenericEndElement(TCSUP,CSUP);
    1582             :     else
    1583           0 :         HandleAccent();
    1584           0 : }
    1585             : 
    1586             : 
    1587           0 : void SmXMLOverContext_Impl::HandleAccent()
    1588             : {
    1589           0 :     const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
    1590             :     OSL_ENSURE (bNodeCheck, "Sub has not two arguments");
    1591           0 :     if (!bNodeCheck)
    1592           0 :         return;
    1593             : 
    1594           0 :     SmToken aToken;
    1595           0 :     aToken.cMathChar = '\0';
    1596           0 :     aToken.eType = TACUTE;
    1597             : 
    1598           0 :     SmAttributNode *pNode = new SmAttributNode(aToken);
    1599           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    1600             : 
    1601           0 :     SmNodeArray aSubNodes;
    1602           0 :     aSubNodes.resize(2);
    1603           0 :     aSubNodes[0] = popOrZero(rNodeStack);
    1604           0 :     aSubNodes[1] = popOrZero(rNodeStack);
    1605           0 :     pNode->SetSubNodes(aSubNodes);
    1606           0 :     pNode->SetScaleMode(SCALE_WIDTH);
    1607           0 :     rNodeStack.push_front(pNode);
    1608             : 
    1609             : }
    1610             : 
    1611             : 
    1612             : 
    1613           0 : class SmXMLUnderOverContext_Impl : public SmXMLSubSupContext_Impl
    1614             : {
    1615             : public:
    1616           0 :     SmXMLUnderOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1617             :         const OUString& rLName)
    1618           0 :         : SmXMLSubSupContext_Impl(rImport,nPrefix,rLName) {}
    1619             : 
    1620           0 :     void EndElement() SAL_OVERRIDE
    1621             :     {
    1622           0 :         GenericEndElement(TCSUB,CSUB,CSUP);
    1623           0 :     }
    1624             : };
    1625             : 
    1626             : 
    1627             : 
    1628           0 : class SmXMLMultiScriptsContext_Impl : public SmXMLSubSupContext_Impl
    1629             : {
    1630             :     bool bHasPrescripts;
    1631             : 
    1632             :     void ProcessSubSupPairs(bool bIsPrescript);
    1633             : 
    1634             : public:
    1635           0 :     SmXMLMultiScriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1636             :         const OUString& rLName) :
    1637             :         SmXMLSubSupContext_Impl(rImport,nPrefix,rLName),
    1638           0 :         bHasPrescripts(false) {}
    1639             : 
    1640             :     void EndElement() SAL_OVERRIDE;
    1641             :     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
    1642             :         const OUString& rLocalName,
    1643             :         const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
    1644             : };
    1645             : 
    1646             : 
    1647             : 
    1648           0 : class SmXMLNoneContext_Impl : public SmXMLImportContext
    1649             : {
    1650             : public:
    1651           0 :     SmXMLNoneContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1652             :         const OUString& rLName)
    1653           0 :         : SmXMLImportContext(rImport,nPrefix,rLName) {}
    1654             : 
    1655             :     void EndElement() SAL_OVERRIDE;
    1656             : };
    1657             : 
    1658             : 
    1659           0 : void SmXMLNoneContext_Impl::EndElement()
    1660             : {
    1661           0 :     SmToken aToken;
    1662           0 :     aToken.cMathChar = '\0';
    1663           0 :     aToken.aText.clear();
    1664           0 :     aToken.nLevel = 5;
    1665           0 :     aToken.eType = TIDENT;
    1666           0 :     GetSmImport().GetNodeStack().push_front(
    1667           0 :         new SmTextNode(aToken,FNT_VARIABLE));
    1668           0 : }
    1669             : 
    1670             : 
    1671             : 
    1672           0 : class SmXMLPrescriptsContext_Impl : public SmXMLImportContext
    1673             : {
    1674             : public:
    1675           0 :     SmXMLPrescriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1676             :         const OUString& rLName)
    1677           0 :         : SmXMLImportContext(rImport,nPrefix,rLName) {}
    1678             : };
    1679             : 
    1680             : 
    1681             : 
    1682           7 : class SmXMLTableRowContext_Impl : public SmXMLRowContext_Impl
    1683             : {
    1684             : public:
    1685           4 :     SmXMLTableRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1686             :         const OUString& rLName) :
    1687           4 :         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
    1688           4 :         {}
    1689             : 
    1690             :     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
    1691             :         const OUString& rLocalName,
    1692             :         const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
    1693             : };
    1694             : 
    1695             : 
    1696             : 
    1697             : 
    1698           2 : class SmXMLTableContext_Impl : public SmXMLTableRowContext_Impl
    1699             : {
    1700             : public:
    1701           1 :     SmXMLTableContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1702             :         const OUString& rLName) :
    1703           1 :         SmXMLTableRowContext_Impl(rImport,nPrefix,rLName)
    1704           1 :         {}
    1705             : 
    1706             :     void EndElement() SAL_OVERRIDE;
    1707             :     SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
    1708             :         const OUString& rLocalName,
    1709             :         const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
    1710             : };
    1711             : 
    1712             : 
    1713             : 
    1714             : 
    1715           0 : class SmXMLTableCellContext_Impl : public SmXMLRowContext_Impl
    1716             : {
    1717             : public:
    1718           0 :     SmXMLTableCellContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1719             :         const OUString& rLName) :
    1720           0 :         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
    1721           0 :         {}
    1722             : };
    1723             : 
    1724             : 
    1725             : 
    1726           0 : class SmXMLAlignGroupContext_Impl : public SmXMLRowContext_Impl
    1727             : {
    1728             : public:
    1729           0 :     SmXMLAlignGroupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1730             :         const OUString& rLName) :
    1731           0 :         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
    1732           0 :         {}
    1733             : 
    1734             :     /*Don't do anything with alignment for now*/
    1735           0 :     void EndElement() SAL_OVERRIDE
    1736             :     {
    1737           0 :     }
    1738             : };
    1739             : 
    1740             : 
    1741             : 
    1742           6 : class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
    1743             : {
    1744             :     size_t mnSelection; // 1-based
    1745             : 
    1746             : public:
    1747           3 :     SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
    1748             :         const OUString& rLName) :
    1749             :         SmXMLRowContext_Impl(rImport,nPrefix,rLName)
    1750           3 :       , mnSelection(1)
    1751           3 :         {}
    1752             : 
    1753             :     void StartElement(const uno::Reference<xml::sax::XAttributeList> &xAttrList) SAL_OVERRIDE;
    1754             :     void EndElement() SAL_OVERRIDE;
    1755             : };
    1756             : 
    1757             : 
    1758             : 
    1759             : // NB: virtually inherit so we can multiply inherit properly
    1760             : //     in SmXMLFlatDocContext_Impl
    1761           4 : class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext
    1762             : {
    1763             : public:
    1764           2 :     SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
    1765             :         const OUString& rLName)
    1766           2 :         : SvXMLImportContext(rImport,nPrfx,rLName) {}
    1767             : 
    1768             :     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
    1769             : };
    1770             : 
    1771           2 : SvXMLImportContext *SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
    1772             :         const OUString& rLocalName,
    1773             :         const uno::Reference< xml::sax::XAttributeList > &xAttrList)
    1774             : {
    1775           2 :     SvXMLImportContext *pContext = 0;
    1776           4 :     if ( XML_NAMESPACE_OFFICE == nPrefix &&
    1777           2 :         rLocalName == GetXMLToken(XML_META) )
    1778             :     {
    1779             :         SAL_WARN("starmath", "XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
    1780             :     }
    1781           4 :     else if ( XML_NAMESPACE_OFFICE == nPrefix &&
    1782           2 :         rLocalName == GetXMLToken(XML_SETTINGS) )
    1783             :     {
    1784           2 :         pContext = new XMLDocumentSettingsContext( GetImport(),
    1785             :                                     XML_NAMESPACE_OFFICE, rLocalName,
    1786           2 :                                     xAttrList );
    1787             :     }
    1788             :     else
    1789           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
    1790             : 
    1791           2 :     return pContext;
    1792             : }
    1793             : 
    1794             : 
    1795             : 
    1796             : // context for flat file xml format
    1797             : class SmXMLFlatDocContext_Impl
    1798             :     : public SmXMLOfficeContext_Impl, public SvXMLMetaDocumentContext
    1799             : {
    1800             : public:
    1801             :     SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
    1802             :         sal_uInt16 i_nPrefix, const OUString & i_rLName,
    1803             :         const uno::Reference<document::XDocumentProperties>& i_xDocProps);
    1804             : 
    1805             :     virtual ~SmXMLFlatDocContext_Impl();
    1806             : 
    1807             :     virtual SvXMLImportContext *CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) SAL_OVERRIDE;
    1808             : };
    1809             : 
    1810           0 : SmXMLFlatDocContext_Impl::SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
    1811             :         sal_uInt16 i_nPrefix, const OUString & i_rLName,
    1812             :         const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
    1813             :     SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
    1814             :     SmXMLOfficeContext_Impl(i_rImport, i_nPrefix, i_rLName),
    1815             :     SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
    1816           0 :         i_xDocProps)
    1817             : {
    1818           0 : }
    1819             : 
    1820           0 : SmXMLFlatDocContext_Impl::~SmXMLFlatDocContext_Impl()
    1821             : {
    1822           0 : }
    1823             : 
    1824           0 : SvXMLImportContext *SmXMLFlatDocContext_Impl::CreateChildContext(
    1825             :     sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
    1826             :     const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
    1827             : {
    1828             :     // behave like meta base class iff we encounter office:meta
    1829           0 :     if ( XML_NAMESPACE_OFFICE == i_nPrefix &&
    1830           0 :             i_rLocalName == GetXMLToken(XML_META) )
    1831             :     {
    1832             :         return SvXMLMetaDocumentContext::CreateChildContext(
    1833           0 :                     i_nPrefix, i_rLocalName, i_xAttrList );
    1834             :     }
    1835             :     else
    1836             :     {
    1837             :         return SmXMLOfficeContext_Impl::CreateChildContext(
    1838           0 :                     i_nPrefix, i_rLocalName, i_xAttrList );
    1839             :     }
    1840             : }
    1841             : 
    1842             : 
    1843             : 
    1844             : static const SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
    1845             : {
    1846             :     { XML_NAMESPACE_MATH,   XML_SEMANTICS, XML_TOK_SEMANTICS },
    1847             :     { XML_NAMESPACE_MATH,   XML_MATH,      XML_TOK_MATH   },
    1848             :     { XML_NAMESPACE_MATH,   XML_MSTYLE,    XML_TOK_MSTYLE  },
    1849             :     { XML_NAMESPACE_MATH,   XML_MERROR,    XML_TOK_MERROR },
    1850             :     { XML_NAMESPACE_MATH,   XML_MPHANTOM,  XML_TOK_MPHANTOM },
    1851             :     { XML_NAMESPACE_MATH,   XML_MROW,      XML_TOK_MROW },
    1852             :     { XML_NAMESPACE_MATH,   XML_MENCLOSE,  XML_TOK_MENCLOSE },
    1853             :     { XML_NAMESPACE_MATH,   XML_MFRAC,     XML_TOK_MFRAC },
    1854             :     { XML_NAMESPACE_MATH,   XML_MSQRT,     XML_TOK_MSQRT },
    1855             :     { XML_NAMESPACE_MATH,   XML_MROOT,     XML_TOK_MROOT },
    1856             :     { XML_NAMESPACE_MATH,   XML_MSUB,      XML_TOK_MSUB },
    1857             :     { XML_NAMESPACE_MATH,   XML_MSUP,      XML_TOK_MSUP },
    1858             :     { XML_NAMESPACE_MATH,   XML_MSUBSUP,   XML_TOK_MSUBSUP },
    1859             :     { XML_NAMESPACE_MATH,   XML_MUNDER,    XML_TOK_MUNDER },
    1860             :     { XML_NAMESPACE_MATH,   XML_MOVER,     XML_TOK_MOVER },
    1861             :     { XML_NAMESPACE_MATH,   XML_MUNDEROVER,    XML_TOK_MUNDEROVER },
    1862             :     { XML_NAMESPACE_MATH,   XML_MMULTISCRIPTS, XML_TOK_MMULTISCRIPTS },
    1863             :     { XML_NAMESPACE_MATH,   XML_MTABLE,    XML_TOK_MTABLE },
    1864             :     { XML_NAMESPACE_MATH,   XML_MACTION,   XML_TOK_MACTION },
    1865             :     { XML_NAMESPACE_MATH,   XML_MFENCED,   XML_TOK_MFENCED },
    1866             :     { XML_NAMESPACE_MATH,   XML_MPADDED,   XML_TOK_MPADDED },
    1867             :     XML_TOKEN_MAP_END
    1868             : };
    1869             : 
    1870             : static const SvXMLTokenMapEntry aPresLayoutAttrTokenMap[] =
    1871             : {
    1872             :     { XML_NAMESPACE_MATH,   XML_FONTWEIGHT,      XML_TOK_FONTWEIGHT    },
    1873             :     { XML_NAMESPACE_MATH,   XML_FONTSTYLE,       XML_TOK_FONTSTYLE     },
    1874             :     { XML_NAMESPACE_MATH,   XML_FONTSIZE,        XML_TOK_FONTSIZE      },
    1875             :     { XML_NAMESPACE_MATH,   XML_FONTFAMILY,      XML_TOK_FONTFAMILY    },
    1876             :     { XML_NAMESPACE_MATH,   XML_COLOR,           XML_TOK_COLOR },
    1877             :     { XML_NAMESPACE_MATH,   XML_MATHCOLOR,       XML_TOK_MATHCOLOR },
    1878             :     XML_TOKEN_MAP_END
    1879             : };
    1880             : 
    1881             : static const SvXMLTokenMapEntry aFencedAttrTokenMap[] =
    1882             : {
    1883             :     { XML_NAMESPACE_MATH,   XML_OPEN,       XML_TOK_OPEN },
    1884             :     { XML_NAMESPACE_MATH,   XML_CLOSE,      XML_TOK_CLOSE },
    1885             :     XML_TOKEN_MAP_END
    1886             : };
    1887             : 
    1888             : static const SvXMLTokenMapEntry aOperatorAttrTokenMap[] =
    1889             : {
    1890             :     { XML_NAMESPACE_MATH,   XML_STRETCHY,      XML_TOK_STRETCHY },
    1891             :     XML_TOKEN_MAP_END
    1892             : };
    1893             : 
    1894             : static const SvXMLTokenMapEntry aAnnotationAttrTokenMap[] =
    1895             : {
    1896             :     { XML_NAMESPACE_MATH,   XML_ENCODING,      XML_TOK_ENCODING },
    1897             :     XML_TOKEN_MAP_END
    1898             : };
    1899             : 
    1900             : 
    1901             : static const SvXMLTokenMapEntry aPresElemTokenMap[] =
    1902             : {
    1903             :     { XML_NAMESPACE_MATH,   XML_ANNOTATION,    XML_TOK_ANNOTATION },
    1904             :     { XML_NAMESPACE_MATH,   XML_MI,    XML_TOK_MI },
    1905             :     { XML_NAMESPACE_MATH,   XML_MN,    XML_TOK_MN },
    1906             :     { XML_NAMESPACE_MATH,   XML_MO,    XML_TOK_MO },
    1907             :     { XML_NAMESPACE_MATH,   XML_MTEXT, XML_TOK_MTEXT },
    1908             :     { XML_NAMESPACE_MATH,   XML_MSPACE,XML_TOK_MSPACE },
    1909             :     { XML_NAMESPACE_MATH,   XML_MS,    XML_TOK_MS },
    1910             :     { XML_NAMESPACE_MATH,   XML_MALIGNGROUP,   XML_TOK_MALIGNGROUP },
    1911             :     XML_TOKEN_MAP_END
    1912             : };
    1913             : 
    1914             : static const SvXMLTokenMapEntry aPresScriptEmptyElemTokenMap[] =
    1915             : {
    1916             :     { XML_NAMESPACE_MATH,   XML_MPRESCRIPTS,   XML_TOK_MPRESCRIPTS },
    1917             :     { XML_NAMESPACE_MATH,   XML_NONE,  XML_TOK_NONE },
    1918             :     XML_TOKEN_MAP_END
    1919             : };
    1920             : 
    1921             : static const SvXMLTokenMapEntry aPresTableElemTokenMap[] =
    1922             : {
    1923             :     { XML_NAMESPACE_MATH,   XML_MTR,       XML_TOK_MTR },
    1924             :     { XML_NAMESPACE_MATH,   XML_MTD,       XML_TOK_MTD },
    1925             :     XML_TOKEN_MAP_END
    1926             : };
    1927             : 
    1928             : static const SvXMLTokenMapEntry aColorTokenMap[] =
    1929             : {
    1930             :     { XML_NAMESPACE_MATH,   XML_BLACK,        TBLACK},
    1931             :     { XML_NAMESPACE_MATH,   XML_WHITE,        TWHITE},
    1932             :     { XML_NAMESPACE_MATH,   XML_RED,          TRED},
    1933             :     { XML_NAMESPACE_MATH,   XML_GREEN,        TGREEN},
    1934             :     { XML_NAMESPACE_MATH,   XML_BLUE,         TBLUE},
    1935             :     { XML_NAMESPACE_MATH,   XML_AQUA,         TAQUA},
    1936             :     { XML_NAMESPACE_MATH,   XML_FUCHSIA,      TFUCHSIA},
    1937             :     { XML_NAMESPACE_MATH,   XML_YELLOW,       TYELLOW},
    1938             :     { XML_NAMESPACE_MATH,   XML_NAVY,         TNAVY},
    1939             :     { XML_NAMESPACE_MATH,   XML_TEAL,         TTEAL},
    1940             :     { XML_NAMESPACE_MATH,   XML_MAROON,       TMAROON},
    1941             :     { XML_NAMESPACE_MATH,   XML_PURPLE,       TPURPLE},
    1942             :     { XML_NAMESPACE_MATH,   XML_OLIVE,        TOLIVE},
    1943             :     { XML_NAMESPACE_MATH,   XML_GRAY,         TGRAY},
    1944             :     { XML_NAMESPACE_MATH,   XML_SILVER,       TSILVER},
    1945             :     { XML_NAMESPACE_MATH,   XML_LIME,         TLIME},
    1946             :     XML_TOKEN_MAP_END
    1947             : };
    1948             : 
    1949             : static const SvXMLTokenMapEntry aActionAttrTokenMap[] =
    1950             : {
    1951             :     { XML_NAMESPACE_MATH,   XML_SELECTION,      XML_TOK_SELECTION },
    1952             :     XML_TOKEN_MAP_END
    1953             : };
    1954             : 
    1955             : 
    1956          17 : const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
    1957             : {
    1958          17 :     if (!pPresLayoutElemTokenMap)
    1959           5 :         pPresLayoutElemTokenMap.reset(new SvXMLTokenMap(aPresLayoutElemTokenMap));
    1960          17 :     return *pPresLayoutElemTokenMap;
    1961             : }
    1962             : 
    1963           0 : const SvXMLTokenMap& SmXMLImport::GetPresLayoutAttrTokenMap()
    1964             : {
    1965           0 :     if (!pPresLayoutAttrTokenMap)
    1966           0 :         pPresLayoutAttrTokenMap.reset(new SvXMLTokenMap(aPresLayoutAttrTokenMap));
    1967           0 :     return *pPresLayoutAttrTokenMap;
    1968             : }
    1969             : 
    1970             : 
    1971           0 : const SvXMLTokenMap& SmXMLImport::GetFencedAttrTokenMap()
    1972             : {
    1973           0 :     if (!pFencedAttrTokenMap)
    1974           0 :         pFencedAttrTokenMap.reset(new SvXMLTokenMap(aFencedAttrTokenMap));
    1975           0 :     return *pFencedAttrTokenMap;
    1976             : }
    1977             : 
    1978           0 : const SvXMLTokenMap& SmXMLImport::GetOperatorAttrTokenMap()
    1979             : {
    1980           0 :     if (!pOperatorAttrTokenMap)
    1981           0 :         pOperatorAttrTokenMap.reset(new SvXMLTokenMap(aOperatorAttrTokenMap));
    1982           0 :     return *pOperatorAttrTokenMap;
    1983             : }
    1984             : 
    1985           2 : const SvXMLTokenMap& SmXMLImport::GetAnnotationAttrTokenMap()
    1986             : {
    1987           2 :     if (!pAnnotationAttrTokenMap)
    1988           2 :         pAnnotationAttrTokenMap.reset(new SvXMLTokenMap(aAnnotationAttrTokenMap));
    1989           2 :     return *pAnnotationAttrTokenMap;
    1990             : }
    1991             : 
    1992          41 : const SvXMLTokenMap& SmXMLImport::GetPresElemTokenMap()
    1993             : {
    1994          41 :     if (!pPresElemTokenMap)
    1995           5 :         pPresElemTokenMap.reset(new SvXMLTokenMap(aPresElemTokenMap));
    1996          41 :     return *pPresElemTokenMap;
    1997             : }
    1998             : 
    1999           0 : const SvXMLTokenMap& SmXMLImport::GetPresScriptEmptyElemTokenMap()
    2000             : {
    2001           0 :     if (!pPresScriptEmptyElemTokenMap)
    2002             :         pPresScriptEmptyElemTokenMap.reset(new
    2003           0 :             SvXMLTokenMap(aPresScriptEmptyElemTokenMap));
    2004           0 :     return *pPresScriptEmptyElemTokenMap;
    2005             : }
    2006             : 
    2007           6 : const SvXMLTokenMap& SmXMLImport::GetPresTableElemTokenMap()
    2008             : {
    2009           6 :     if (!pPresTableElemTokenMap)
    2010           1 :         pPresTableElemTokenMap.reset(new SvXMLTokenMap(aPresTableElemTokenMap));
    2011           6 :     return *pPresTableElemTokenMap;
    2012             : }
    2013             : 
    2014           0 : const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
    2015             : {
    2016           0 :     if (!pColorTokenMap)
    2017           0 :         pColorTokenMap.reset(new SvXMLTokenMap(aColorTokenMap));
    2018           0 :     return *pColorTokenMap;
    2019             : }
    2020             : 
    2021           5 : const SvXMLTokenMap& SmXMLImport::GetActionAttrTokenMap()
    2022             : {
    2023           5 :     if (!pActionAttrTokenMap)
    2024           1 :         pActionAttrTokenMap.reset(new SvXMLTokenMap(aActionAttrTokenMap));
    2025           5 :     return *pActionAttrTokenMap;
    2026             : }
    2027             : 
    2028             : 
    2029          17 : SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
    2030             :     sal_uInt16 nPrefix,
    2031             :     const OUString& rLocalName,
    2032             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2033             : {
    2034          17 :     SvXMLImportContext* pContext = 0L;
    2035             : 
    2036          17 :     const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresLayoutElemTokenMap();
    2037             : 
    2038          17 :     switch(rTokenMap.Get(nPrefix, rLocalName))
    2039             :     {
    2040             :         //Consider semantics a dummy except for any starmath annotations
    2041             :         case XML_TOK_SEMANTICS:
    2042           2 :             pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
    2043           4 :                 xAttrList);
    2044           2 :             break;
    2045             :         /*General Layout Schemata*/
    2046             :         case XML_TOK_MROW:
    2047           3 :             pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
    2048           6 :                 xAttrList);
    2049           3 :             break;
    2050             :         case XML_TOK_MENCLOSE:
    2051           0 :             pContext = GetSmImport().CreateEncloseContext(nPrefix,rLocalName,
    2052           0 :                 xAttrList);
    2053           0 :             break;
    2054             :         case XML_TOK_MFRAC:
    2055           0 :             pContext = GetSmImport().CreateFracContext(nPrefix,rLocalName,
    2056           0 :                 xAttrList);
    2057           0 :             break;
    2058             :         case XML_TOK_MSQRT:
    2059           0 :             pContext = GetSmImport().CreateSqrtContext(nPrefix,rLocalName,
    2060           0 :                 xAttrList);
    2061           0 :             break;
    2062             :         case XML_TOK_MROOT:
    2063           0 :             pContext = GetSmImport().CreateRootContext(nPrefix,rLocalName,
    2064           0 :                 xAttrList);
    2065           0 :             break;
    2066             :         case XML_TOK_MSTYLE:
    2067           0 :             pContext = GetSmImport().CreateStyleContext(nPrefix,rLocalName,
    2068           0 :                 xAttrList);
    2069           0 :             break;
    2070             :         case XML_TOK_MERROR:
    2071           0 :             pContext = GetSmImport().CreateErrorContext(nPrefix,rLocalName,
    2072           0 :                 xAttrList);
    2073           0 :             break;
    2074             :         case XML_TOK_MPADDED:
    2075           0 :             pContext = GetSmImport().CreatePaddedContext(nPrefix,rLocalName,
    2076           0 :                 xAttrList);
    2077           0 :             break;
    2078             :         case XML_TOK_MPHANTOM:
    2079           0 :             pContext = GetSmImport().CreatePhantomContext(nPrefix,rLocalName,
    2080           0 :                 xAttrList);
    2081           0 :             break;
    2082             :         case XML_TOK_MFENCED:
    2083           2 :             pContext = GetSmImport().CreateFencedContext(nPrefix,rLocalName,
    2084           4 :                 xAttrList);
    2085           2 :             break;
    2086             :         /*Script and Limit Schemata*/
    2087             :         case XML_TOK_MSUB:
    2088           0 :             pContext = GetSmImport().CreateSubContext(nPrefix,rLocalName,
    2089           0 :                 xAttrList);
    2090           0 :             break;
    2091             :         case XML_TOK_MSUP:
    2092           2 :             pContext = GetSmImport().CreateSupContext(nPrefix,rLocalName,
    2093           4 :                 xAttrList);
    2094           2 :             break;
    2095             :         case XML_TOK_MSUBSUP:
    2096           4 :             pContext = GetSmImport().CreateSubSupContext(nPrefix,rLocalName,
    2097           8 :                 xAttrList);
    2098           4 :             break;
    2099             :         case XML_TOK_MUNDER:
    2100           0 :             pContext = GetSmImport().CreateUnderContext(nPrefix,rLocalName,
    2101           0 :                 xAttrList);
    2102           0 :             break;
    2103             :         case XML_TOK_MOVER:
    2104           0 :             pContext = GetSmImport().CreateOverContext(nPrefix,rLocalName,
    2105           0 :                 xAttrList);
    2106           0 :             break;
    2107             :         case XML_TOK_MUNDEROVER:
    2108           0 :             pContext = GetSmImport().CreateUnderOverContext(nPrefix,rLocalName,
    2109           0 :                 xAttrList);
    2110           0 :             break;
    2111             :         case XML_TOK_MMULTISCRIPTS:
    2112           0 :             pContext = GetSmImport().CreateMultiScriptsContext(nPrefix,
    2113           0 :                 rLocalName, xAttrList);
    2114           0 :             break;
    2115             :         case XML_TOK_MTABLE:
    2116           1 :             pContext = GetSmImport().CreateTableContext(nPrefix,
    2117           2 :                 rLocalName, xAttrList);
    2118           1 :             break;
    2119             :         case XML_TOK_MACTION:
    2120           3 :             pContext = GetSmImport().CreateActionContext(nPrefix,
    2121           6 :                 rLocalName, xAttrList);
    2122           3 :             break;
    2123             :         default:
    2124             :             /*Basically theres an implicit mrow around certain bare
    2125             :              *elements, use a RowContext to see if this is one of
    2126             :              *those ones*/
    2127           0 :             SmXMLRowContext_Impl aTempContext(GetSmImport(),nPrefix,
    2128           0 :                 GetXMLToken(XML_MROW));
    2129             : 
    2130             :             pContext = aTempContext.StrictCreateChildContext(nPrefix,
    2131           0 :                 rLocalName, xAttrList);
    2132           0 :             break;
    2133             :     }
    2134          17 :     return pContext;
    2135             : }
    2136             : 
    2137           5 : void SmXMLDocContext_Impl::EndElement()
    2138             : {
    2139           5 :     SmNodeArray ContextArray;
    2140           5 :     ContextArray.resize(1);
    2141           5 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2142             : 
    2143           5 :     ContextArray[0] = popOrZero(rNodeStack);
    2144             : 
    2145          10 :     SmToken aDummy;
    2146           5 :     SmStructureNode *pSNode = new SmLineNode(aDummy);
    2147           5 :     pSNode->SetSubNodes(ContextArray);
    2148           5 :     rNodeStack.push_front(pSNode);
    2149             : 
    2150          10 :     SmNodeArray  LineArray;
    2151           5 :     auto n = rNodeStack.size();
    2152           5 :     LineArray.resize(n);
    2153          10 :     for (size_t j = 0; j < n; j++)
    2154             :     {
    2155           5 :         auto pNode = rNodeStack.pop_front();
    2156           5 :         LineArray[n - (j + 1)] = pNode.release();
    2157           5 :     }
    2158           5 :     SmStructureNode *pSNode2 = new SmTableNode(aDummy);
    2159           5 :     pSNode2->SetSubNodes(LineArray);
    2160          10 :     rNodeStack.push_front(pSNode2);
    2161           5 : }
    2162             : 
    2163           0 : void SmXMLFracContext_Impl::EndElement()
    2164             : {
    2165           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2166           0 :     const bool bNodeCheck = rNodeStack.size() - nElementCount == 2;
    2167             :     OSL_ENSURE( bNodeCheck, "Fraction (mfrac) tag is missing component" );
    2168           0 :     if (!bNodeCheck)
    2169           0 :         return;
    2170             : 
    2171           0 :     SmToken aToken;
    2172           0 :     aToken.cMathChar = '\0';
    2173           0 :     aToken.eType = TOVER;
    2174           0 :     SmStructureNode *pSNode = new SmBinVerNode(aToken);
    2175           0 :     SmNode *pOper = new SmRectangleNode(aToken);
    2176           0 :     SmNode *pSecond = popOrZero(rNodeStack);
    2177           0 :     SmNode *pFirst = popOrZero(rNodeStack);
    2178           0 :     pSNode->SetSubNodes(pFirst,pOper,pSecond);
    2179           0 :     rNodeStack.push_front(pSNode);
    2180             : }
    2181             : 
    2182           0 : void SmXMLRootContext_Impl::EndElement()
    2183             : {
    2184             :     /*The <mroot> element requires exactly 2 arguments.*/
    2185           0 :     const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
    2186             :     OSL_ENSURE( bNodeCheck, "Root tag is missing component");
    2187           0 :     if (!bNodeCheck)
    2188           0 :         return;
    2189             : 
    2190           0 :     SmToken aToken;
    2191           0 :     aToken.cMathChar = MS_SQRT;  //Temporary: alert, based on StarSymbol font
    2192           0 :     aToken.eType = TNROOT;
    2193           0 :     SmStructureNode *pSNode = new SmRootNode(aToken);
    2194           0 :     SmNode *pOper = new SmRootSymbolNode(aToken);
    2195           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2196           0 :     SmNode *pIndex = popOrZero(rNodeStack);
    2197           0 :     SmNode *pBase = popOrZero(rNodeStack);
    2198           0 :     pSNode->SetSubNodes(pIndex,pOper,pBase);
    2199           0 :     rNodeStack.push_front(pSNode);
    2200             : }
    2201             : 
    2202           0 : void SmXMLSqrtContext_Impl::EndElement()
    2203             : {
    2204             :     /*
    2205             :     <msqrt> accepts any number of arguments; if this number is not 1, its
    2206             :     contents are treated as a single "inferred <mrow>" containing its
    2207             :     arguments
    2208             :     */
    2209           0 :     if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
    2210           0 :         SmXMLRowContext_Impl::EndElement();
    2211             : 
    2212           0 :     SmToken aToken;
    2213           0 :     aToken.cMathChar = MS_SQRT;  //Temporary: alert, based on StarSymbol font
    2214           0 :     aToken.eType = TSQRT;
    2215           0 :     SmStructureNode *pSNode = new SmRootNode(aToken);
    2216           0 :     SmNode *pOper = new SmRootSymbolNode(aToken);
    2217           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2218           0 :     pSNode->SetSubNodes(0,pOper,popOrZero(rNodeStack));
    2219           0 :     rNodeStack.push_front(pSNode);
    2220           0 : }
    2221             : 
    2222           8 : void SmXMLRowContext_Impl::EndElement()
    2223             : {
    2224           8 :     SmNodeArray aRelationArray;
    2225           8 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2226             : 
    2227           8 :     if (rNodeStack.size() > nElementCount)
    2228             :     {
    2229           8 :         auto nSize = rNodeStack.size() - nElementCount;
    2230             : 
    2231           8 :         aRelationArray.resize(nSize);
    2232          20 :         for (auto j=nSize;j > 0;j--)
    2233             :         {
    2234          12 :             auto pNode = rNodeStack.pop_front();
    2235          12 :             aRelationArray[j-1] = pNode.release();
    2236          12 :         }
    2237             : 
    2238             :         //If the first or last element is an operator with stretchyness
    2239             :         //set then we must create a brace node here from those elements,
    2240             :         //removing the stretchness from the operators and applying it to
    2241             :         //ourselves, and creating the appropriate dummy StarMath none bracket
    2242             :         //to balance the arrangement
    2243          16 :         if (((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
    2244           0 :             && (aRelationArray[0]->GetType() == NMATH))
    2245          16 :         || ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
    2246           0 :             && (aRelationArray[nSize-1]->GetType() == NMATH)))
    2247             :         {
    2248           0 :             SmToken aToken;
    2249           0 :             aToken.cMathChar = '\0';
    2250           0 :             aToken.nLevel = 5;
    2251             : 
    2252           0 :             int nLeft=0,nRight=0;
    2253           0 :             if ((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
    2254           0 :                 && (aRelationArray[0]->GetType() == NMATH))
    2255             :             {
    2256           0 :                 aToken = aRelationArray[0]->GetToken();
    2257           0 :                 nLeft=1;
    2258             :             }
    2259             :             else
    2260           0 :                 aToken.cMathChar = '\0';
    2261             : 
    2262           0 :             aToken.eType = TLPARENT;
    2263           0 :             SmNode *pLeft = new SmMathSymbolNode(aToken);
    2264             : 
    2265           0 :             if ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
    2266           0 :                 && (aRelationArray[nSize-1]->GetType() == NMATH))
    2267             :             {
    2268           0 :                 aToken = aRelationArray[nSize-1]->GetToken();
    2269           0 :                 nRight=1;
    2270             :             }
    2271             :             else
    2272           0 :                 aToken.cMathChar = '\0';
    2273             : 
    2274           0 :             aToken.eType = TRPARENT;
    2275           0 :             SmNode *pRight = new SmMathSymbolNode(aToken);
    2276             : 
    2277           0 :             SmNodeArray aRelationArray2;
    2278             : 
    2279             :             //!! nSize-nLeft-nRight may be < 0 !!
    2280           0 :             int nRelArrSize = nSize-nLeft-nRight;
    2281           0 :             if (nRelArrSize > 0)
    2282             :             {
    2283           0 :                 aRelationArray2.resize(nRelArrSize);
    2284           0 :                 for (int i=0;i < nRelArrSize;i++)
    2285           0 :                     aRelationArray2[i] = aRelationArray[i+nLeft];
    2286             :             }
    2287             : 
    2288           0 :             SmToken aDummy;
    2289           0 :             SmStructureNode *pSNode = new SmBraceNode(aToken);
    2290           0 :             SmStructureNode *pBody = new SmExpressionNode(aDummy);
    2291           0 :             pBody->SetSubNodes(aRelationArray2);
    2292             : 
    2293           0 :             pSNode->SetSubNodes(pLeft,pBody,pRight);
    2294           0 :             pSNode->SetScaleMode(SCALE_HEIGHT);
    2295           0 :             rNodeStack.push_front(pSNode);
    2296           8 :             return;
    2297             :         }
    2298             :     }
    2299             :     else //Multiple newlines result in empty row elements
    2300             :     {
    2301           0 :         aRelationArray.resize(1);
    2302           0 :         SmToken aToken;
    2303           0 :         aToken.cMathChar = '\0';
    2304           0 :         aToken.nLevel = 5;
    2305           0 :         aToken.eType = TNEWLINE;
    2306           0 :         aRelationArray[0] = new SmLineNode(aToken);
    2307             :     }
    2308             : 
    2309          16 :     SmToken aDummy;
    2310           8 :     SmStructureNode *pSNode = new SmExpressionNode(aDummy);
    2311           8 :     pSNode->SetSubNodes(aRelationArray);
    2312          16 :     rNodeStack.push_front(pSNode);
    2313             : }
    2314             : 
    2315             : 
    2316          41 : SvXMLImportContext *SmXMLRowContext_Impl::StrictCreateChildContext(
    2317             :     sal_uInt16 nPrefix,
    2318             :     const OUString& rLocalName,
    2319             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2320             : {
    2321          41 :     SvXMLImportContext* pContext = 0L;
    2322             : 
    2323          41 :     const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresElemTokenMap();
    2324          41 :     switch(rTokenMap.Get(nPrefix, rLocalName))
    2325             :     {
    2326             :         /*Note that these should accept malignmark subelements, but do not*/
    2327             :         case XML_TOK_MN:
    2328          15 :             pContext = GetSmImport().CreateNumberContext(nPrefix,rLocalName,
    2329          30 :                 xAttrList);
    2330          15 :             break;
    2331             :         case XML_TOK_MI:
    2332          10 :             pContext = GetSmImport().CreateIdentifierContext(nPrefix,rLocalName,
    2333          20 :                 xAttrList);
    2334          10 :             break;
    2335             :         case XML_TOK_MO:
    2336           2 :             pContext = GetSmImport().CreateOperatorContext(nPrefix,rLocalName,
    2337           4 :                 xAttrList);
    2338           2 :             break;
    2339             :         case XML_TOK_MTEXT:
    2340           0 :             pContext = GetSmImport().CreateTextContext(nPrefix,rLocalName,
    2341           0 :                 xAttrList);
    2342           0 :             break;
    2343             :         case XML_TOK_MSPACE:
    2344           0 :             pContext = GetSmImport().CreateSpaceContext(nPrefix,rLocalName,
    2345           0 :                 xAttrList);
    2346           0 :             break;
    2347             :         case XML_TOK_MS:
    2348           0 :             pContext = GetSmImport().CreateStringContext(nPrefix,rLocalName,
    2349           0 :                 xAttrList);
    2350           0 :             break;
    2351             : 
    2352             :         /*Note: The maligngroup should only be seen when the row
    2353             :          * (or descendants) are in a table*/
    2354             :         case XML_TOK_MALIGNGROUP:
    2355           0 :             pContext = GetSmImport().CreateAlignGroupContext(nPrefix,rLocalName,
    2356           0 :                 xAttrList);
    2357           0 :             break;
    2358             : 
    2359             :         case XML_TOK_ANNOTATION:
    2360           2 :             pContext = GetSmImport().CreateAnnotationContext(nPrefix,rLocalName,
    2361           4 :                 xAttrList);
    2362           2 :             break;
    2363             : 
    2364             :         default:
    2365          12 :             break;
    2366             :     }
    2367          41 :     return pContext;
    2368             : }
    2369             : 
    2370             : 
    2371          41 : SvXMLImportContext *SmXMLRowContext_Impl::CreateChildContext(
    2372             :     sal_uInt16 nPrefix,
    2373             :     const OUString& rLocalName,
    2374             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2375             : {
    2376             :     SvXMLImportContext* pContext = StrictCreateChildContext(nPrefix,
    2377          41 :     rLocalName, xAttrList);
    2378             : 
    2379          41 :     if (!pContext)
    2380             :     {
    2381             :         //Hmm, unrecognized for this level, check to see if its
    2382             :         //an element that can have an implicit schema around it
    2383             :         pContext = SmXMLDocContext_Impl::CreateChildContext(nPrefix,
    2384          12 :             rLocalName,xAttrList);
    2385             :     }
    2386          41 :     return pContext;
    2387             : }
    2388             : 
    2389             : 
    2390           0 : SvXMLImportContext *SmXMLMultiScriptsContext_Impl::CreateChildContext(
    2391             :     sal_uInt16 nPrefix,
    2392             :     const OUString& rLocalName,
    2393             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2394             : {
    2395           0 :     SvXMLImportContext* pContext = 0L;
    2396             : 
    2397           0 :     const SvXMLTokenMap& rTokenMap = GetSmImport().
    2398           0 :         GetPresScriptEmptyElemTokenMap();
    2399           0 :     switch(rTokenMap.Get(nPrefix, rLocalName))
    2400             :     {
    2401             :         case XML_TOK_MPRESCRIPTS:
    2402           0 :             bHasPrescripts = true;
    2403           0 :             ProcessSubSupPairs(false);
    2404           0 :             pContext = GetSmImport().CreatePrescriptsContext(nPrefix,
    2405           0 :                 rLocalName, xAttrList);
    2406           0 :             break;
    2407             :         case XML_TOK_NONE:
    2408           0 :             pContext = GetSmImport().CreateNoneContext(nPrefix,rLocalName,
    2409           0 :                 xAttrList);
    2410           0 :             break;
    2411             :         default:
    2412             :             pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
    2413           0 :                 rLocalName,xAttrList);
    2414           0 :             break;
    2415             :     }
    2416           0 :     return pContext;
    2417             : }
    2418             : 
    2419           0 : void SmXMLMultiScriptsContext_Impl::ProcessSubSupPairs(bool bIsPrescript)
    2420             : {
    2421           0 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2422             : 
    2423           0 :     if (rNodeStack.size() <= nElementCount)
    2424           0 :         return;
    2425             : 
    2426           0 :     auto nCount = rNodeStack.size() - nElementCount - 1;
    2427           0 :     if (nCount == 0)
    2428           0 :         return;
    2429             : 
    2430           0 :     if (nCount % 2 == 0)
    2431             :     {
    2432           0 :         SmToken aToken;
    2433           0 :         aToken.cMathChar = '\0';
    2434           0 :         aToken.eType = bIsPrescript ? TLSUB : TRSUB;
    2435             : 
    2436           0 :         SmNodeStack aReverseStack;
    2437           0 :         for (size_t i = 0; i < nCount + 1; i++)
    2438             :         {
    2439           0 :             auto pNode = rNodeStack.pop_front();
    2440           0 :             aReverseStack.push_front(pNode.release());
    2441           0 :         }
    2442             : 
    2443           0 :         SmSubSup eSub = bIsPrescript ? LSUB : RSUB;
    2444           0 :         SmSubSup eSup = bIsPrescript ? LSUP : RSUP;
    2445             : 
    2446           0 :         for (size_t i = 0; i < nCount; i += 2)
    2447             :         {
    2448           0 :             SmSubSupNode *pNode = new SmSubSupNode(aToken);
    2449             : 
    2450             :             // initialize subnodes array
    2451           0 :             SmNodeArray aSubNodes(1 + SUBSUP_NUM_ENTRIES);
    2452             : 
    2453             :             /*On each loop the base and its sub sup pair becomes the
    2454             :              base for the next loop to which the next sub sup pair is
    2455             :              attached, i.e. wheels within wheels*/
    2456           0 :             aSubNodes[0] = popOrZero(aReverseStack);
    2457             : 
    2458           0 :             SmNode *pScriptNode = popOrZero(aReverseStack);
    2459             : 
    2460           0 :             if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
    2461           0 :                 (!pScriptNode->GetToken().aText.isEmpty())))
    2462           0 :                 aSubNodes[eSub+1] = pScriptNode;
    2463           0 :             pScriptNode = popOrZero(aReverseStack);
    2464           0 :             if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
    2465           0 :                 (!pScriptNode->GetToken().aText.isEmpty())))
    2466           0 :                 aSubNodes[eSup+1] = pScriptNode;
    2467             : 
    2468           0 :             pNode->SetSubNodes(aSubNodes);
    2469           0 :             aReverseStack.push_front(pNode);
    2470           0 :         }
    2471             :         assert(!aReverseStack.empty());
    2472           0 :         auto pNode = aReverseStack.pop_front();
    2473           0 :         rNodeStack.push_front(pNode.release());
    2474             :     }
    2475             :     else
    2476             :     {
    2477             :         // Ignore odd number of elements.
    2478           0 :         for (size_t i = 0; i < nCount; i++)
    2479             :         {
    2480           0 :             rNodeStack.pop_front();
    2481             :         }
    2482             :     }
    2483             : }
    2484             : 
    2485             : 
    2486           1 : void SmXMLTableContext_Impl::EndElement()
    2487             : {
    2488           1 :     SmNodeArray aExpressionArray;
    2489           1 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2490           2 :     SmNodeStack aReverseStack;
    2491           1 :     aExpressionArray.resize(rNodeStack.size()-nElementCount);
    2492             : 
    2493           1 :     auto nRows = rNodeStack.size()-nElementCount;
    2494           1 :     sal_uInt16 nCols = 0;
    2495             : 
    2496             :     SmStructureNode *pArray;
    2497           4 :     for (auto i=nRows;i > 0;i--)
    2498             :     {
    2499           3 :         auto pNode = rNodeStack.pop_front();
    2500           3 :         pArray = static_cast<SmStructureNode *>(pNode.release());
    2501           3 :         if (pArray->GetNumSubNodes() == 0)
    2502             :         {
    2503             :             //This is a little tricky, it is possible that there was
    2504             :             //be elements that were not inside a <mtd> pair, in which
    2505             :             //case they will not be in a row, i.e. they will not have
    2506             :             //SubNodes, so we have to wait until here before we can
    2507             :             //resolve the situation. Implicitsurrounding tags are
    2508             :             //surprisingly difficult to get right within this
    2509             :             //architecture
    2510             : 
    2511           0 :             SmNodeArray aRelationArray;
    2512           0 :             aRelationArray.resize(1);
    2513           0 :             aRelationArray[0] = pArray;
    2514           0 :             SmToken aDummy;
    2515           0 :             pArray = new SmExpressionNode(aDummy);
    2516           0 :             pArray->SetSubNodes(aRelationArray);
    2517             :         }
    2518             : 
    2519           3 :         if (pArray->GetNumSubNodes() > nCols)
    2520           1 :             nCols = pArray->GetNumSubNodes();
    2521           3 :         aReverseStack.push_front(pArray);
    2522           3 :     }
    2523           1 :     aExpressionArray.resize(nCols*nRows);
    2524           1 :     size_t j=0;
    2525           5 :     while ( !aReverseStack.empty() )
    2526             :     {
    2527           3 :         auto pNode = aReverseStack.pop_front();
    2528           3 :         pArray = static_cast<SmStructureNode *>(pNode.release());
    2529           6 :         for (sal_uInt16 i=0;i<pArray->GetNumSubNodes();i++)
    2530           3 :             aExpressionArray[j++] = pArray->GetSubNode(i);
    2531           3 :     }
    2532             : 
    2533           2 :     SmToken aToken;
    2534           1 :     aToken.cMathChar = '\0';
    2535           1 :     aToken.nGroup = TRGROUP;
    2536           1 :     aToken.eType = TMATRIX;
    2537           1 :     SmMatrixNode *pSNode = new SmMatrixNode(aToken);
    2538           1 :     pSNode->SetSubNodes(aExpressionArray);
    2539           1 :     pSNode->SetRowCol(static_cast<sal_uInt16>(nRows),nCols);
    2540           2 :     rNodeStack.push_front(pSNode);
    2541           1 : }
    2542             : 
    2543           3 : SvXMLImportContext *SmXMLTableRowContext_Impl::CreateChildContext(
    2544             :     sal_uInt16 nPrefix,
    2545             :     const OUString& rLocalName,
    2546             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2547             : {
    2548           3 :     SvXMLImportContext* pContext = 0L;
    2549             : 
    2550           3 :     const SvXMLTokenMap& rTokenMap = GetSmImport().
    2551           3 :         GetPresTableElemTokenMap();
    2552           3 :     switch(rTokenMap.Get(nPrefix, rLocalName))
    2553             :     {
    2554             :         case XML_TOK_MTD:
    2555           0 :             pContext = GetSmImport().CreateTableCellContext(nPrefix,
    2556           0 :                 rLocalName, xAttrList);
    2557           0 :             break;
    2558             :         default:
    2559             :             pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
    2560           3 :                 rLocalName,xAttrList);
    2561           3 :             break;
    2562             :     }
    2563           3 :     return pContext;
    2564             : }
    2565             : 
    2566           3 : SvXMLImportContext *SmXMLTableContext_Impl::CreateChildContext(
    2567             :     sal_uInt16 nPrefix,
    2568             :     const OUString& rLocalName,
    2569             :     const uno::Reference<xml::sax::XAttributeList>& xAttrList)
    2570             : {
    2571           3 :     SvXMLImportContext* pContext = 0L;
    2572             : 
    2573           3 :     const SvXMLTokenMap& rTokenMap = GetSmImport().
    2574           3 :         GetPresTableElemTokenMap();
    2575           3 :     switch(rTokenMap.Get(nPrefix, rLocalName))
    2576             :     {
    2577             :         case XML_TOK_MTR:
    2578           3 :             pContext = GetSmImport().CreateTableRowContext(nPrefix,rLocalName,
    2579           6 :                 xAttrList);
    2580           3 :             break;
    2581             :         default:
    2582             :             pContext = SmXMLTableRowContext_Impl::CreateChildContext(nPrefix,
    2583           0 :                 rLocalName,xAttrList);
    2584           0 :             break;
    2585             :     }
    2586           3 :     return pContext;
    2587             : }
    2588             : 
    2589           0 : void SmXMLMultiScriptsContext_Impl::EndElement()
    2590             : {
    2591           0 :     ProcessSubSupPairs(bHasPrescripts);
    2592           0 : }
    2593             : 
    2594           3 : void SmXMLActionContext_Impl::StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)
    2595             : {
    2596           3 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
    2597           8 :     for (sal_Int16 i=0;i<nAttrCount;i++)
    2598             :     {
    2599           5 :         OUString sAttrName = xAttrList->getNameByIndex(i);
    2600          10 :         OUString aLocalName;
    2601           5 :         sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
    2602           5 :             GetKeyByAttrName(sAttrName,&aLocalName);
    2603             : 
    2604          10 :         OUString sValue = xAttrList->getValueByIndex(i);
    2605             :         const SvXMLTokenMap &rAttrTokenMap =
    2606           5 :             GetSmImport().GetActionAttrTokenMap();
    2607           5 :         switch(rAttrTokenMap.Get(nPrefix,aLocalName))
    2608             :         {
    2609             :             case XML_TOK_SELECTION:
    2610             :                 {
    2611           2 :                     sal_uInt32 n = sValue.toUInt32();
    2612           2 :                     if (n > 0) mnSelection = static_cast<size_t>(n);
    2613             :                 }
    2614           2 :                 break;
    2615             :             default:
    2616           3 :                 break;
    2617             :         }
    2618           5 :     }
    2619           3 : }
    2620             : 
    2621           3 : void SmXMLActionContext_Impl::EndElement()
    2622             : {
    2623           3 :     SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
    2624           3 :     auto nSize = rNodeStack.size();
    2625           3 :     if (nSize <= nElementCount) {
    2626             :         // not compliant to maction's specification, e.g., no subexpressions
    2627           3 :         return;
    2628             :     }
    2629             :     assert(mnSelection > 0);
    2630           3 :     if (nSize < nElementCount + mnSelection) {
    2631             :         // No selected subexpression exists, which is a MathML error;
    2632             :         // fallback to selecting the first
    2633           0 :         mnSelection = 1;
    2634             :     }
    2635             :     assert(nSize >= nElementCount + mnSelection);
    2636           6 :     for (auto i=nSize-(nElementCount+mnSelection); i > 0; i--)
    2637             :     {
    2638           3 :         rNodeStack.pop_front();
    2639             :     }
    2640           3 :     auto pSelected = rNodeStack.pop_front();
    2641           6 :     for (auto i=rNodeStack.size()-nElementCount; i > 0; i--)
    2642             :     {
    2643           3 :         rNodeStack.pop_front();
    2644             :     }
    2645           3 :     rNodeStack.push_front(pSelected.release());
    2646             : }
    2647             : 
    2648           7 : SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
    2649             :     const OUString &rLocalName,
    2650             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2651             : {
    2652           7 :     if ( XML_NAMESPACE_OFFICE == nPrefix )
    2653             :     {
    2654           4 :         if ( (IsXMLToken(rLocalName, XML_DOCUMENT) ||
    2655           2 :               IsXMLToken(rLocalName, XML_DOCUMENT_META)))
    2656             :         {
    2657             :             uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
    2658           0 :                 GetModel(), uno::UNO_QUERY_THROW);
    2659           0 :             return IsXMLToken(rLocalName, XML_DOCUMENT_META)
    2660             :                 ? new SvXMLMetaDocumentContext(*this,
    2661             :                         XML_NAMESPACE_OFFICE, rLocalName,
    2662           0 :                         xDPS->getDocumentProperties())
    2663             :                 // flat OpenDocument file format -- this has not been tested...
    2664             :                 : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
    2665           0 :                             xDPS->getDocumentProperties());
    2666             :         }
    2667             :         else
    2668             :         {
    2669           2 :             return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
    2670             :         }
    2671             :     }
    2672             :     else
    2673           5 :         return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
    2674             : }
    2675             : 
    2676           5 : SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
    2677             :     const OUString &rLocalName,
    2678             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2679             : {
    2680           5 :         return new SmXMLRowContext_Impl(*this,nPrefix,rLocalName);
    2681             : }
    2682             : 
    2683           0 : SvXMLImportContext *SmXMLImport::CreateTextContext(sal_uInt16 nPrefix,
    2684             :     const OUString &rLocalName,
    2685             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2686             : {
    2687           0 :     return new SmXMLTextContext_Impl(*this,nPrefix,rLocalName);
    2688             : }
    2689             : 
    2690           2 : SvXMLImportContext *SmXMLImport::CreateAnnotationContext(sal_uInt16 nPrefix,
    2691             :     const OUString &rLocalName,
    2692             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2693             : {
    2694           2 :     return new SmXMLAnnotationContext_Impl(*this,nPrefix,rLocalName);
    2695             : }
    2696             : 
    2697           0 : SvXMLImportContext *SmXMLImport::CreateStringContext(sal_uInt16 nPrefix,
    2698             :     const OUString &rLocalName,
    2699             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2700             : {
    2701           0 :     return new SmXMLStringContext_Impl(*this,nPrefix,rLocalName);
    2702             : }
    2703             : 
    2704          15 : SvXMLImportContext *SmXMLImport::CreateNumberContext(sal_uInt16 nPrefix,
    2705             :     const OUString &rLocalName,
    2706             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2707             : {
    2708          15 :     return new SmXMLNumberContext_Impl(*this,nPrefix,rLocalName);
    2709             : }
    2710             : 
    2711          10 : SvXMLImportContext *SmXMLImport::CreateIdentifierContext(sal_uInt16 nPrefix,
    2712             :     const OUString &rLocalName,
    2713             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2714             : {
    2715          10 :     return new SmXMLIdentifierContext_Impl(*this,nPrefix,rLocalName);
    2716             : }
    2717             : 
    2718           2 : SvXMLImportContext *SmXMLImport::CreateOperatorContext(sal_uInt16 nPrefix,
    2719             :     const OUString &rLocalName,
    2720             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2721             : {
    2722           2 :     return new SmXMLOperatorContext_Impl(*this,nPrefix,rLocalName);
    2723             : }
    2724             : 
    2725           0 : SvXMLImportContext *SmXMLImport::CreateSpaceContext(sal_uInt16 nPrefix,
    2726             :     const OUString &rLocalName,
    2727             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2728             : {
    2729           0 :     return new SmXMLSpaceContext_Impl(*this,nPrefix,rLocalName);
    2730             : }
    2731             : 
    2732             : 
    2733           0 : SvXMLImportContext *SmXMLImport::CreateEncloseContext(sal_uInt16 nPrefix,
    2734             :     const OUString &rLocalName,
    2735             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2736             : {
    2737           0 :     return new SmXMLEncloseContext_Impl(*this,nPrefix,rLocalName);
    2738             : }
    2739             : 
    2740           0 : SvXMLImportContext *SmXMLImport::CreateFracContext(sal_uInt16 nPrefix,
    2741             :     const OUString &rLocalName,
    2742             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2743             : {
    2744           0 :     return new SmXMLFracContext_Impl(*this,nPrefix,rLocalName);
    2745             : }
    2746             : 
    2747           0 : SvXMLImportContext *SmXMLImport::CreateSqrtContext(sal_uInt16 nPrefix,
    2748             :     const OUString &rLocalName,
    2749             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2750             : {
    2751           0 :     return new SmXMLSqrtContext_Impl(*this,nPrefix,rLocalName);
    2752             : }
    2753             : 
    2754           0 : SvXMLImportContext *SmXMLImport::CreateRootContext(sal_uInt16 nPrefix,
    2755             :     const OUString &rLocalName,
    2756             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2757             : {
    2758           0 :     return new SmXMLRootContext_Impl(*this,nPrefix,rLocalName);
    2759             : }
    2760             : 
    2761           0 : SvXMLImportContext *SmXMLImport::CreateStyleContext(sal_uInt16 nPrefix,
    2762             :     const OUString &rLocalName,
    2763             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2764             : {
    2765           0 :     return new SmXMLStyleContext_Impl(*this,nPrefix,rLocalName);
    2766             : }
    2767             : 
    2768           0 : SvXMLImportContext *SmXMLImport::CreatePaddedContext(sal_uInt16 nPrefix,
    2769             :     const OUString &rLocalName,
    2770             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2771             : {
    2772           0 :     return new SmXMLPaddedContext_Impl(*this,nPrefix,rLocalName);
    2773             : }
    2774             : 
    2775           0 : SvXMLImportContext *SmXMLImport::CreatePhantomContext(sal_uInt16 nPrefix,
    2776             :     const OUString &rLocalName,
    2777             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2778             : {
    2779           0 :     return new SmXMLPhantomContext_Impl(*this,nPrefix,rLocalName);
    2780             : }
    2781             : 
    2782           2 : SvXMLImportContext *SmXMLImport::CreateFencedContext(sal_uInt16 nPrefix,
    2783             :     const OUString &rLocalName,
    2784             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2785             : {
    2786           2 :     return new SmXMLFencedContext_Impl(*this,nPrefix,rLocalName);
    2787             : }
    2788             : 
    2789           0 : SvXMLImportContext *SmXMLImport::CreateErrorContext(sal_uInt16 nPrefix,
    2790             :     const OUString &rLocalName,
    2791             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2792             : {
    2793           0 :     return new SmXMLErrorContext_Impl(*this,nPrefix,rLocalName);
    2794             : }
    2795             : 
    2796           0 : SvXMLImportContext *SmXMLImport::CreateSubContext(sal_uInt16 nPrefix,
    2797             :     const OUString &rLocalName,
    2798             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2799             : {
    2800           0 :     return new SmXMLSubContext_Impl(*this,nPrefix,rLocalName);
    2801             : }
    2802             : 
    2803           4 : SvXMLImportContext *SmXMLImport::CreateSubSupContext(sal_uInt16 nPrefix,
    2804             :     const OUString &rLocalName,
    2805             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2806             : {
    2807           4 :     return new SmXMLSubSupContext_Impl(*this,nPrefix,rLocalName);
    2808             : }
    2809             : 
    2810           2 : SvXMLImportContext *SmXMLImport::CreateSupContext(sal_uInt16 nPrefix,
    2811             :     const OUString &rLocalName,
    2812             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2813             : {
    2814           2 :     return new SmXMLSupContext_Impl(*this,nPrefix,rLocalName);
    2815             : }
    2816             : 
    2817           0 : SvXMLImportContext *SmXMLImport::CreateUnderContext(sal_uInt16 nPrefix,
    2818             :     const OUString &rLocalName,
    2819             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2820             : {
    2821           0 :         return new SmXMLUnderContext_Impl(*this,nPrefix,rLocalName);
    2822             : }
    2823             : 
    2824           0 : SvXMLImportContext *SmXMLImport::CreateOverContext(sal_uInt16 nPrefix,
    2825             :     const OUString &rLocalName,
    2826             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2827             : {
    2828           0 :     return new SmXMLOverContext_Impl(*this,nPrefix,rLocalName);
    2829             : }
    2830             : 
    2831           0 : SvXMLImportContext *SmXMLImport::CreateUnderOverContext(sal_uInt16 nPrefix,
    2832             :     const OUString &rLocalName,
    2833             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2834             : {
    2835           0 :     return new SmXMLUnderOverContext_Impl(*this,nPrefix,rLocalName);
    2836             : }
    2837             : 
    2838           0 : SvXMLImportContext *SmXMLImport::CreateMultiScriptsContext(sal_uInt16 nPrefix,
    2839             :     const OUString &rLocalName,
    2840             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2841             : {
    2842           0 :     return new SmXMLMultiScriptsContext_Impl(*this,nPrefix,rLocalName);
    2843             : }
    2844             : 
    2845           1 : SvXMLImportContext *SmXMLImport::CreateTableContext(sal_uInt16 nPrefix,
    2846             :     const OUString &rLocalName,
    2847             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2848             : {
    2849           1 :     return new SmXMLTableContext_Impl(*this,nPrefix,rLocalName);
    2850             : }
    2851           3 : SvXMLImportContext *SmXMLImport::CreateTableRowContext(sal_uInt16 nPrefix,
    2852             :     const OUString &rLocalName,
    2853             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2854             : {
    2855           3 :     return new SmXMLTableRowContext_Impl(*this,nPrefix,rLocalName);
    2856             : }
    2857           0 : SvXMLImportContext *SmXMLImport::CreateTableCellContext(sal_uInt16 nPrefix,
    2858             :     const OUString &rLocalName,
    2859             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2860             : {
    2861           0 :     return new SmXMLTableCellContext_Impl(*this,nPrefix,rLocalName);
    2862             : }
    2863             : 
    2864           0 : SvXMLImportContext *SmXMLImport::CreateNoneContext(sal_uInt16 nPrefix,
    2865             :     const OUString &rLocalName,
    2866             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2867             : {
    2868           0 :     return new SmXMLNoneContext_Impl(*this,nPrefix,rLocalName);
    2869             : }
    2870             : 
    2871           0 : SvXMLImportContext *SmXMLImport::CreatePrescriptsContext(sal_uInt16 nPrefix,
    2872             :     const OUString &rLocalName,
    2873             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2874             : {
    2875           0 :     return new SmXMLPrescriptsContext_Impl(*this,nPrefix,rLocalName);
    2876             : }
    2877             : 
    2878           0 : SvXMLImportContext *SmXMLImport::CreateAlignGroupContext(sal_uInt16 nPrefix,
    2879             :     const OUString &rLocalName,
    2880             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2881             : {
    2882           0 :     return new SmXMLAlignGroupContext_Impl(*this,nPrefix,rLocalName);
    2883             : }
    2884             : 
    2885           3 : SvXMLImportContext *SmXMLImport::CreateActionContext(sal_uInt16 nPrefix,
    2886             :     const OUString &rLocalName,
    2887             :     const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
    2888             : {
    2889           3 :     return new SmXMLActionContext_Impl(*this,nPrefix,rLocalName);
    2890             : }
    2891             : 
    2892          32 : SmXMLImport::~SmXMLImport() throw ()
    2893             : {
    2894          32 : }
    2895             : 
    2896           2 : void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
    2897             : {
    2898           2 :     uno::Reference <frame::XModel> xModel = GetModel();
    2899           2 :     if ( !xModel.is() )
    2900           0 :         return;
    2901             : 
    2902           4 :     uno::Reference <lang::XUnoTunnel> xTunnel;
    2903           2 :     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
    2904             :     SmModel *pModel = reinterpret_cast<SmModel *>
    2905           2 :         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
    2906             : 
    2907           2 :     if ( !pModel )
    2908           0 :         return;
    2909             : 
    2910             :     SmDocShell *pDocShell =
    2911           2 :         static_cast<SmDocShell*>(pModel->GetObjectShell());
    2912           2 :     if ( !pDocShell )
    2913           0 :         return;
    2914             : 
    2915           2 :     Rectangle aRect( pDocShell->GetVisArea() );
    2916             : 
    2917           2 :     sal_Int32 nCount = aViewProps.getLength();
    2918           2 :     const PropertyValue *pValue = aViewProps.getConstArray();
    2919             : 
    2920           2 :     long nTmp = 0;
    2921             : 
    2922          10 :     for (sal_Int32 i = 0; i < nCount ; i++)
    2923             :     {
    2924           8 :         if (pValue->Name == "ViewAreaTop" )
    2925             :         {
    2926           2 :             pValue->Value >>= nTmp;
    2927           2 :             aRect.setY( nTmp );
    2928             :         }
    2929           6 :         else if (pValue->Name == "ViewAreaLeft" )
    2930             :         {
    2931           2 :             pValue->Value >>= nTmp;
    2932           2 :             aRect.setX( nTmp );
    2933             :         }
    2934           4 :         else if (pValue->Name == "ViewAreaWidth" )
    2935             :         {
    2936           2 :             pValue->Value >>= nTmp;
    2937           2 :             Size aSize( aRect.GetSize() );
    2938           2 :             aSize.Width() = nTmp;
    2939           2 :             aRect.SetSize( aSize );
    2940             :         }
    2941           2 :         else if (pValue->Name == "ViewAreaHeight" )
    2942             :         {
    2943           2 :             pValue->Value >>= nTmp;
    2944           2 :             Size aSize( aRect.GetSize() );
    2945           2 :             aSize.Height() = nTmp;
    2946           2 :             aRect.SetSize( aSize );
    2947             :         }
    2948           8 :         pValue++;
    2949             :     }
    2950             : 
    2951           4 :     pDocShell->SetVisArea ( aRect );
    2952             : }
    2953             : 
    2954           2 : void SmXMLImport::SetConfigurationSettings(const Sequence<PropertyValue>& aConfProps)
    2955             : {
    2956           2 :     uno::Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
    2957           2 :     if ( xProps.is() )
    2958             :     {
    2959           2 :         Reference < XPropertySetInfo > xInfo ( xProps->getPropertySetInfo() );
    2960           2 :         if (xInfo.is() )
    2961             :         {
    2962           2 :             sal_Int32 nCount = aConfProps.getLength();
    2963           2 :             const PropertyValue* pValues = aConfProps.getConstArray();
    2964             : 
    2965           2 :             const OUString sFormula ( "Formula" );
    2966           4 :             const OUString sBasicLibraries ( "BasicLibraries" );
    2967           4 :             const OUString sDialogLibraries ( "DialogLibraries" );
    2968         120 :             while ( nCount-- )
    2969             :             {
    2970         348 :                 if (pValues->Name != sFormula &&
    2971         232 :                     pValues->Name != sBasicLibraries &&
    2972         116 :                     pValues->Name != sDialogLibraries)
    2973             :                 {
    2974             :                     try
    2975             :                     {
    2976         116 :                         if ( xInfo->hasPropertyByName( pValues->Name ) )
    2977         116 :                             xProps->setPropertyValue( pValues->Name, pValues->Value );
    2978             :                     }
    2979           0 :                     catch (const beans::PropertyVetoException &)
    2980             :                     {
    2981             :                         // dealing with read-only properties here. Nothing to do...
    2982             :                     }
    2983           0 :                     catch( Exception& rEx)
    2984             :                     {
    2985             :                         SAL_WARN("starmath", "SmXMLImport::SetConfigurationSettings: Exception: " << rEx.Message );
    2986             :                     }
    2987             :                 }
    2988             : 
    2989         116 :                 pValues++;
    2990           2 :             }
    2991           2 :         }
    2992           2 :     }
    2993          44 : }
    2994             : 
    2995             : 
    2996             : 
    2997             : 
    2998             : 
    2999             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11