Bump version to 5.0-14
[LibreOffice.git] / starmath / source / mathmlimport.cxx
blob2a8179ef34d64aff0e9d27f97a27022aac372331
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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*/
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>
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>
63 #include <memory>
65 #include "mathmlimport.hxx"
66 #include "register.hxx"
67 #include <starmath.hrc>
68 #include <unomodel.hxx>
69 #include <document.hxx>
70 #include <utility.hxx>
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;
81 #define IMPORT_SVC_NAME "com.sun.star.xml.XMLImportFilter"
84 sal_uLong SmXMLImportWrapper::Import(SfxMedium &rMedium)
86 sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
88 uno::Reference<uno::XComponentContext> xContext( comphelper::getProcessComponentContext() );
90 //Make a model component from our SmModel
91 uno::Reference< lang::XComponent > xModelComp( xModel, uno::UNO_QUERY );
92 OSL_ENSURE( xModelComp.is(), "XMLReader::Read: got no model" );
94 // try to get an XStatusIndicator from the Medium
95 uno::Reference<task::XStatusIndicator> xStatusIndicator;
97 bool bEmbedded = false;
98 uno::Reference <lang::XUnoTunnel> xTunnel;
99 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
100 SmModel *pModel = reinterpret_cast<SmModel *>
101 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
103 SmDocShell *pDocShell = pModel ?
104 static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
105 if (pDocShell)
107 OSL_ENSURE( pDocShell->GetMedium() == &rMedium,
108 "different SfxMedium found" );
110 SfxItemSet* pSet = rMedium.GetItemSet();
111 if (pSet)
113 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
114 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
115 if (pItem)
116 pItem->GetValue() >>= xStatusIndicator;
119 if ( SfxObjectCreateMode::EMBEDDED == pDocShell->GetCreateMode() )
120 bEmbedded = true;
123 comphelper::PropertyMapEntry aInfoMap[] =
125 { OUString("PrivateData"), 0,
126 cppu::UnoType<XInterface>::get(),
127 beans::PropertyAttribute::MAYBEVOID, 0 },
128 { OUString("BaseURI"), 0,
129 ::cppu::UnoType<OUString>::get(),
130 beans::PropertyAttribute::MAYBEVOID, 0 },
131 { OUString("StreamRelPath"), 0,
132 ::cppu::UnoType<OUString>::get(),
133 beans::PropertyAttribute::MAYBEVOID, 0 },
134 { OUString("StreamName"), 0,
135 ::cppu::UnoType<OUString>::get(),
136 beans::PropertyAttribute::MAYBEVOID, 0 },
137 { OUString(), 0, css::uno::Type(), 0, 0 }
139 uno::Reference< beans::XPropertySet > xInfoSet(
140 comphelper::GenericPropertySet_CreateInstance(
141 new comphelper::PropertySetInfo( aInfoMap ) ) );
143 // Set base URI
144 OUString sPropName( "BaseURI" );
145 xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL() ) );
147 sal_Int32 nSteps=3;
148 if ( !(rMedium.IsStorage()))
149 nSteps = 1;
151 sal_Int32 nProgressRange(nSteps);
152 if (xStatusIndicator.is())
154 xStatusIndicator->start(SM_RESSTR(STR_STATSTR_READING), nProgressRange);
157 nSteps=0;
158 if (xStatusIndicator.is())
159 xStatusIndicator->setValue(nSteps++);
161 if ( rMedium.IsStorage())
163 // TODO/LATER: handle the case of embedded links gracefully
164 if ( bEmbedded ) // && !rMedium.GetStorage()->IsRoot() )
166 OUString aName( "dummyObjName" );
167 if ( rMedium.GetItemSet() )
169 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
170 rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
171 if ( pDocHierarchItem )
172 aName = pDocHierarchItem->GetValue();
175 if ( !aName.isEmpty() )
177 sPropName = "StreamRelPath";
178 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
182 bool bOASIS = ( SotStorage::GetVersion( rMedium.GetStorage() ) > SOFFICE_FILEFORMAT_60 );
183 if (xStatusIndicator.is())
184 xStatusIndicator->setValue(nSteps++);
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 : "com.sun.star.comp.Math.XMLMetaImporter") );
192 if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
194 if (xStatusIndicator.is())
195 xStatusIndicator->setValue(nSteps++);
197 nWarn = ReadThroughComponent(
198 rMedium.GetStorage(), xModelComp, "settings.xml", 0,
199 xContext, xInfoSet,
200 (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsImporter"
201 : "com.sun.star.comp.Math.XMLSettingsImporter" ) );
203 if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
205 if (xStatusIndicator.is())
206 xStatusIndicator->setValue(nSteps++);
208 nError = ReadThroughComponent(
209 rMedium.GetStorage(), xModelComp, "content.xml", "Content.xml",
210 xContext, xInfoSet, "com.sun.star.comp.Math.XMLImporter" );
212 else
213 nError = ERRCODE_IO_BROKENPACKAGE;
215 else
216 nError = ERRCODE_IO_BROKENPACKAGE;
218 else
220 Reference<io::XInputStream> xInputStream =
221 new utl::OInputStreamWrapper(rMedium.GetInStream());
223 if (xStatusIndicator.is())
224 xStatusIndicator->setValue(nSteps++);
226 nError = ReadThroughComponent( xInputStream, xModelComp,
227 xContext, xInfoSet, "com.sun.star.comp.Math.XMLImporter", false );
230 if (xStatusIndicator.is())
231 xStatusIndicator->end();
232 return nError;
236 /// read a component (file + filter version)
237 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 )
245 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!");
251 // prepare ParserInputSrouce
252 xml::sax::InputSource aParserInput;
253 aParserInput.aInputStream = xInputStream;
255 // get parser
256 Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(rxContext);
258 Sequence<Any> aArgs( 1 );
259 aArgs[0] <<= rPropSet;
261 // get filter
262 Reference< xml::sax::XDocumentHandler > xFilter(
263 rxContext->getServiceManager()->createInstanceWithArgumentsAndContext(
264 OUString::createFromAscii(pFilterName), aArgs, rxContext),
265 UNO_QUERY );
266 OSL_ENSURE( xFilter.is(), "Can't instantiate filter component." );
267 if ( !xFilter.is() )
268 return nError;
270 // connect parser and filter
271 xParser->setDocumentHandler( xFilter );
273 // connect model and filter
274 Reference < XImporter > xImporter( xFilter, UNO_QUERY );
275 xImporter->setTargetDocument( xModelComponent );
277 // finally, parser the stream
280 xParser->parseStream( aParserInput );
282 uno::Reference<lang::XUnoTunnel> xFilterTunnel;
283 xFilterTunnel = uno::Reference<lang::XUnoTunnel>
284 ( xFilter, uno::UNO_QUERY );
285 SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
286 sal::static_int_cast< sal_uIntPtr >(
287 xFilterTunnel->getSomething( SmXMLImport::getUnoTunnelId() )));
288 if ( pFilter && pFilter->GetSuccess() )
289 nError = 0;
291 catch( xml::sax::SAXParseException& r )
293 // sax parser sends wrapped exceptions,
294 // try to find the original one
295 xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
296 bool bTryChild = true;
298 while( bTryChild )
300 xml::sax::SAXException aTmp;
301 if ( aSaxEx.WrappedException >>= aTmp )
302 aSaxEx = aTmp;
303 else
304 bTryChild = false;
307 packages::zip::ZipIOException aBrokenPackage;
308 if ( aSaxEx.WrappedException >>= aBrokenPackage )
309 return ERRCODE_IO_BROKENPACKAGE;
311 if ( bEncrypted )
312 nError = ERRCODE_SFX_WRONGPASSWORD;
314 catch( const xml::sax::SAXException& r )
316 packages::zip::ZipIOException aBrokenPackage;
317 if ( r.WrappedException >>= aBrokenPackage )
318 return ERRCODE_IO_BROKENPACKAGE;
320 if ( bEncrypted )
321 nError = ERRCODE_SFX_WRONGPASSWORD;
323 catch( packages::zip::ZipIOException& )
325 nError = ERRCODE_IO_BROKENPACKAGE;
327 catch( io::IOException& )
331 return nError;
335 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 )
344 OSL_ENSURE(xStorage.is(), "Need storage!");
345 OSL_ENSURE(NULL != pStreamName, "Please, please, give me a name!");
347 // open stream (and set parser input)
348 OUString sStreamName = OUString::createFromAscii(pStreamName);
349 uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
350 if ( !xAccess->hasByName(sStreamName) || !xStorage->isStreamElement(sStreamName) )
352 // stream name not found! Then try the compatibility name.
353 // do we even have an alternative name?
354 if ( pCompatibilityStreamName )
355 sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
358 // get input stream
361 uno::Reference < io::XStream > xEventsStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
363 // determine if stream is encrypted or not
364 uno::Reference < beans::XPropertySet > xProps( xEventsStream, uno::UNO_QUERY );
365 Any aAny = xProps->getPropertyValue( "Encrypted" );
366 bool bEncrypted = false;
367 if ( aAny.getValueType() == cppu::UnoType<bool>::get() )
368 aAny >>= bEncrypted;
370 // set Base URL
371 if ( rPropSet.is() )
373 OUString sPropName( "StreamName");
374 rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
378 Reference < io::XInputStream > xStream = xEventsStream->getInputStream();
379 return ReadThroughComponent( xStream, xModelComponent, rxContext, rPropSet, pFilterName, bEncrypted );
381 catch ( packages::WrongPasswordException& )
383 return ERRCODE_SFX_WRONGPASSWORD;
385 catch( packages::zip::ZipIOException& )
387 return ERRCODE_IO_BROKENPACKAGE;
389 catch ( uno::Exception& )
393 return ERRCODE_SFX_DOLOADFAILED;
398 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 bSuccess(false)
406 namespace
408 class theSmXMLImportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSmXMLImportUnoTunnelId> {};
411 const uno::Sequence< sal_Int8 > & SmXMLImport::getUnoTunnelId() throw()
413 return theSmXMLImportUnoTunnelId::get().getSeq();
416 OUString SAL_CALL SmXMLImport_getImplementationName() throw()
418 return OUString( "com.sun.star.comp.Math.XMLImporter" );
421 uno::Sequence< OUString > SAL_CALL SmXMLImport_getSupportedServiceNames()
422 throw()
424 return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
427 uno::Reference< uno::XInterface > SAL_CALL SmXMLImport_createInstance(
428 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
429 throw( uno::Exception )
431 return (cppu::OWeakObject*)new SmXMLImport(comphelper::getComponentContext(rSMgr), SmXMLImport_getImplementationName(), SvXMLImportFlags::ALL);
436 OUString SAL_CALL SmXMLImportMeta_getImplementationName() throw()
438 return OUString( "com.sun.star.comp.Math.XMLOasisMetaImporter" );
441 uno::Sequence< OUString > SAL_CALL SmXMLImportMeta_getSupportedServiceNames()
442 throw()
444 return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
447 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportMeta_createInstance(
448 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
449 throw( uno::Exception )
451 return (cppu::OWeakObject*)new SmXMLImport( comphelper::getComponentContext(rSMgr), SmXMLImportMeta_getImplementationName(), SvXMLImportFlags::META );
456 OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw()
458 return OUString( "com.sun.star.comp.Math.XMLOasisSettingsImporter" );
461 uno::Sequence< OUString > SAL_CALL SmXMLImportSettings_getSupportedServiceNames()
462 throw()
464 return uno::Sequence<OUString>{ IMPORT_SVC_NAME };
467 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportSettings_createInstance(
468 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
469 throw( uno::Exception )
471 return (cppu::OWeakObject*)new SmXMLImport( comphelper::getComponentContext(rSMgr), SmXMLImportSettings_getImplementationName(), SvXMLImportFlags::SETTINGS );
474 sal_Int64 SAL_CALL SmXMLImport::getSomething(
475 const uno::Sequence< sal_Int8 >&rId )
476 throw(uno::RuntimeException, std::exception)
478 if ( rId.getLength() == 16 &&
479 0 == memcmp( getUnoTunnelId().getConstArray(),
480 rId.getConstArray(), 16 ) )
481 return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
483 return SvXMLImport::getSomething( rId );
486 void SmXMLImport::endDocument()
487 throw(xml::sax::SAXException, uno::RuntimeException, std::exception)
489 //Set the resulted tree into the SmDocShell where it belongs
490 SmNode *pTree;
491 if (NULL != (pTree = GetTree()))
493 uno::Reference <frame::XModel> xModel = GetModel();
494 uno::Reference <lang::XUnoTunnel> xTunnel;
495 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
496 SmModel *pModel = reinterpret_cast<SmModel *>
497 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
499 if (pModel)
501 SmDocShell *pDocShell =
502 static_cast<SmDocShell*>(pModel->GetObjectShell());
503 pDocShell->SetFormulaTree(pTree);
504 if (aText.isEmpty()) //If we picked up no annotation text
506 // Get text from imported formula
507 pTree->CreateTextFromNode(aText);
508 aText = comphelper::string::stripEnd(aText, ' ');
511 // Convert symbol names
512 SmParser &rParser = pDocShell->GetParser();
513 bool bVal = rParser.IsImportSymbolNames();
514 rParser.SetImportSymbolNames( true );
515 SmNode *pTmpTree = rParser.Parse( aText );
516 aText = rParser.GetText();
517 delete pTmpTree;
518 rParser.SetImportSymbolNames( bVal );
520 pDocShell->SetText( aText );
522 OSL_ENSURE(pModel,"So there *was* a uno problem after all");
524 bSuccess = true;
527 SvXMLImport::endDocument();
532 class SmXMLImportContext: public SvXMLImportContext
534 public:
535 SmXMLImportContext( SmXMLImport &rImport, sal_uInt16 nPrfx,
536 const OUString& rLName)
537 : SvXMLImportContext(rImport, nPrfx, rLName) {}
539 SmXMLImport& GetSmImport()
541 return static_cast<SmXMLImport&>(GetImport());
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;
549 void SmXMLImportContext::TCharacters(const OUString & /*rChars*/)
553 void SmXMLImportContext::Characters(const OUString &rChars)
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).
561 //collapsing not done yet!
562 const OUString &rChars2 = rChars.trim();
563 if (!rChars2.isEmpty())
564 TCharacters(rChars2/*.collapse()*/);
567 SvXMLImportContext * SmXMLImportContext::CreateChildContext(sal_uInt16 /*nPrefix*/,
568 const OUString& /*rLocalName*/,
569 const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/)
571 return 0;
576 struct SmXMLContext_Helper
578 sal_Int8 nIsBold;
579 sal_Int8 nIsItalic;
580 double nFontSize;
581 bool bFontNodeNeeded;
582 OUString sFontFamily;
583 OUString sColor;
585 SmXMLImportContext rContext;
587 explicit SmXMLContext_Helper(SmXMLImportContext &rImport)
588 : nIsBold( -1 )
589 , nIsItalic( -1 )
590 , nFontSize( 0.0 )
591 , bFontNodeNeeded( false )
592 , rContext( rImport )
595 void RetrieveAttrs(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
596 void ApplyAttrs();
599 void SmXMLContext_Helper::RetrieveAttrs(const uno::Reference<
600 xml::sax::XAttributeList > & xAttrList )
602 sal_Int8 nOldIsBold=nIsBold;
603 sal_Int8 nOldIsItalic=nIsItalic;
604 double nOldFontSize=nFontSize;
605 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
606 OUString sOldFontFamily = sFontFamily;
607 for (sal_Int16 i=0;i<nAttrCount;i++)
609 OUString sAttrName = xAttrList->getNameByIndex(i);
610 OUString aLocalName;
611 sal_uInt16 nPrefix = rContext.GetSmImport().GetNamespaceMap().
612 GetKeyByAttrName(sAttrName,&aLocalName);
613 OUString sValue = xAttrList->getValueByIndex(i);
614 const SvXMLTokenMap &rAttrTokenMap =
615 rContext.GetSmImport().GetPresLayoutAttrTokenMap();
616 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
618 case XML_TOK_FONTWEIGHT:
619 nIsBold = sal_Int8(sValue.equals(GetXMLToken(XML_BOLD)));
620 break;
621 case XML_TOK_FONTSTYLE:
622 nIsItalic = sal_Int8(sValue.equals(GetXMLToken(XML_ITALIC)));
623 break;
624 case XML_TOK_FONTSIZE:
625 ::sax::Converter::convertDouble(nFontSize, sValue);
626 rContext.GetSmImport().GetMM100UnitConverter().
627 SetXMLMeasureUnit(util::MeasureUnit::POINT);
628 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
630 if (-1 == sValue.indexOf('%'))
631 nFontSize=0.0;
632 else
634 rContext.GetSmImport().GetMM100UnitConverter().
635 SetXMLMeasureUnit(util::MeasureUnit::PERCENT);
638 break;
639 case XML_TOK_FONTFAMILY:
640 sFontFamily = sValue;
641 break;
642 case XML_TOK_COLOR:
643 sColor = sValue;
644 break;
645 case XML_TOK_MATHCOLOR:
646 sColor = sValue;
647 break;
648 default:
649 break;
653 if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
654 (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
655 || !sColor.isEmpty())
656 bFontNodeNeeded=true;
657 else
658 bFontNodeNeeded=false;
661 void SmXMLContext_Helper::ApplyAttrs()
663 SmNodeStack &rNodeStack = rContext.GetSmImport().GetNodeStack();
665 if (bFontNodeNeeded)
667 SmToken aToken;
668 aToken.cMathChar = '\0';
669 aToken.nLevel = 5;
671 if (nIsBold != -1)
673 if (nIsBold)
674 aToken.eType = TBOLD;
675 else
676 aToken.eType = TNBOLD;
677 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
678 (new SmFontNode(aToken));
679 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
680 rNodeStack.push_front(pFontNode);
682 if (nIsItalic != -1)
684 if (nIsItalic)
685 aToken.eType = TITALIC;
686 else
687 aToken.eType = TNITALIC;
688 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
689 (new SmFontNode(aToken));
690 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
691 rNodeStack.push_front(pFontNode);
693 if (nFontSize != 0.0)
695 aToken.eType = TSIZE;
696 SmFontNode *pFontNode = new SmFontNode(aToken);
698 if (util::MeasureUnit::PERCENT == rContext.GetSmImport()
699 .GetMM100UnitConverter().GetXMLMeasureUnit())
701 if (nFontSize < 100.00)
702 pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
703 FontSizeType::DIVIDE);
704 else
705 pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
706 FontSizeType::MULTIPLY);
708 else
709 pFontNode->SetSizeParameter(Fraction(nFontSize),FontSizeType::ABSOLUT);
711 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
712 rNodeStack.push_front(pFontNode);
714 if (!sFontFamily.isEmpty())
716 if (sFontFamily.equalsIgnoreAsciiCase(GetXMLToken(XML_FIXED)))
717 aToken.eType = TFIXED;
718 else if (sFontFamily.equalsIgnoreAsciiCase("sans"))
719 aToken.eType = TSANS;
720 else if (sFontFamily.equalsIgnoreAsciiCase("serif"))
721 aToken.eType = TSERIF;
722 else //Just give up, we need to extend our font mechanism to be
723 //more general
724 return;
726 aToken.aText = sFontFamily;
727 SmFontNode *pFontNode = new SmFontNode(aToken);
728 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
729 rNodeStack.push_front(pFontNode);
731 if (!sColor.isEmpty())
733 //Again we can only handle a small set of colours in
734 //StarMath for now.
735 const SvXMLTokenMap& rTokenMap =
736 rContext.GetSmImport().GetColorTokenMap();
737 sal_uInt16 tok = rTokenMap.Get(XML_NAMESPACE_MATH, sColor);
738 if (tok != XML_TOK_UNKNOWN)
740 aToken.eType = static_cast<SmTokenType>(tok);
741 SmFontNode *pFontNode = new SmFontNode(aToken);
742 pFontNode->SetSubNodes(0,popOrZero(rNodeStack));
743 rNodeStack.push_front(pFontNode);
752 class SmXMLDocContext_Impl : public SmXMLImportContext
754 public:
755 SmXMLDocContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
756 const OUString& rLName)
757 : SmXMLImportContext(rImport,nPrfx,rLName) {}
759 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
761 void EndElement() SAL_OVERRIDE;
766 /*avert thy gaze from the proginator*/
767 class SmXMLRowContext_Impl : public SmXMLDocContext_Impl
769 protected:
770 size_t nElementCount;
772 public:
773 SmXMLRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
774 const OUString& rLName)
775 : SmXMLDocContext_Impl(rImport,nPrefix,rLName)
776 { nElementCount = GetSmImport().GetNodeStack().size(); }
778 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
780 SvXMLImportContext *StrictCreateChildContext(sal_uInt16 nPrefix,
781 const OUString& rLocalName,
782 const uno::Reference< xml::sax::XAttributeList > &xAttrList);
784 void EndElement() SAL_OVERRIDE;
789 class SmXMLEncloseContext_Impl : public SmXMLRowContext_Impl
791 public:
792 // TODO/LATER: convert <menclose notation="horizontalstrike"> into
793 // "overstrike{}" and extend the Math syntax to support more notations
794 SmXMLEncloseContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
795 const OUString& rLName)
796 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
798 void EndElement() SAL_OVERRIDE;
801 void SmXMLEncloseContext_Impl::EndElement()
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
808 if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
809 SmXMLRowContext_Impl::EndElement();
814 class SmXMLFracContext_Impl : public SmXMLRowContext_Impl
816 public:
817 // TODO/LATER: convert <mfrac bevelled="true"> into "wideslash{}{}"
818 SmXMLFracContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
819 const OUString& rLName)
820 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
822 void EndElement() SAL_OVERRIDE;
827 class SmXMLSqrtContext_Impl : public SmXMLRowContext_Impl
829 public:
830 SmXMLSqrtContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
831 const OUString& rLName)
832 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
834 void EndElement() SAL_OVERRIDE;
839 class SmXMLRootContext_Impl : public SmXMLRowContext_Impl
841 public:
842 SmXMLRootContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
843 const OUString& rLName)
844 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
846 void EndElement() SAL_OVERRIDE;
851 class SmXMLStyleContext_Impl : public SmXMLRowContext_Impl
853 protected:
854 SmXMLContext_Helper aStyleHelper;
856 public:
857 /*Right now the style tag is completely ignored*/
858 SmXMLStyleContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
859 const OUString& rLName) : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
860 aStyleHelper(*this) {}
862 void EndElement() SAL_OVERRIDE;
863 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
866 void SmXMLStyleContext_Impl::StartElement(const uno::Reference<
867 xml::sax::XAttributeList > & xAttrList )
869 aStyleHelper.RetrieveAttrs(xAttrList);
873 void SmXMLStyleContext_Impl::EndElement()
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
880 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
881 if (rNodeStack.size() - nElementCount > 1)
882 SmXMLRowContext_Impl::EndElement();
883 aStyleHelper.ApplyAttrs();
888 class SmXMLPaddedContext_Impl : public SmXMLRowContext_Impl
890 public:
891 /*Right now the style tag is completely ignored*/
892 SmXMLPaddedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
893 const OUString& rLName)
894 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
896 void EndElement() SAL_OVERRIDE;
899 void SmXMLPaddedContext_Impl::EndElement()
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
906 if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
907 SmXMLRowContext_Impl::EndElement();
912 class SmXMLPhantomContext_Impl : public SmXMLRowContext_Impl
914 public:
915 /*Right now the style tag is completely ignored*/
916 SmXMLPhantomContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
917 const OUString& rLName)
918 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
920 void EndElement() SAL_OVERRIDE;
923 void SmXMLPhantomContext_Impl::EndElement()
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
930 if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
931 SmXMLRowContext_Impl::EndElement();
933 SmToken aToken;
934 aToken.cMathChar = '\0';
935 aToken.nLevel = 5;
936 aToken.eType = TPHANTOM;
938 SmStructureNode *pPhantom = static_cast<SmStructureNode *>
939 (new SmFontNode(aToken));
940 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
941 pPhantom->SetSubNodes(0,popOrZero(rNodeStack));
942 rNodeStack.push_front(pPhantom);
947 class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
949 protected:
950 sal_Unicode cBegin;
951 sal_Unicode cEnd;
953 public:
954 SmXMLFencedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
955 const OUString& rLName)
956 : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
957 cBegin('('), cEnd(')') {}
959 void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE;
960 void EndElement() SAL_OVERRIDE;
964 void SmXMLFencedContext_Impl::StartElement(const uno::Reference<
965 xml::sax::XAttributeList > & xAttrList )
967 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
968 for (sal_Int16 i=0;i<nAttrCount;i++)
970 OUString sAttrName = xAttrList->getNameByIndex(i);
971 OUString aLocalName;
972 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
973 GetKeyByAttrName(sAttrName,&aLocalName);
974 OUString sValue = xAttrList->getValueByIndex(i);
975 const SvXMLTokenMap &rAttrTokenMap =
976 GetSmImport().GetFencedAttrTokenMap();
977 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
979 //temp, starmath cannot handle multichar brackets (I think)
980 case XML_TOK_OPEN:
981 cBegin = sValue[0];
982 break;
983 case XML_TOK_CLOSE:
984 cEnd = sValue[0];
985 break;
986 default:
987 /*Go to superclass*/
988 break;
994 void SmXMLFencedContext_Impl::EndElement()
996 SmToken aToken;
997 aToken.cMathChar = '\0';
998 aToken.aText = ",";
999 aToken.eType = TLEFT;
1000 aToken.nLevel = 5;
1002 aToken.eType = TLPARENT;
1003 aToken.cMathChar = cBegin;
1004 SmStructureNode *pSNode = new SmBraceNode(aToken);
1005 SmNode *pLeft = new SmMathSymbolNode(aToken);
1007 aToken.cMathChar = cEnd;
1008 aToken.eType = TRPARENT;
1009 SmNode *pRight = new SmMathSymbolNode(aToken);
1011 SmNodeArray aRelationArray;
1012 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1014 aToken.cMathChar = '\0';
1015 aToken.aText = ",";
1016 aToken.eType = TIDENT;
1018 auto i = rNodeStack.size() - nElementCount;
1019 if (rNodeStack.size() - nElementCount > 1)
1020 i += rNodeStack.size() - 1 - nElementCount;
1021 aRelationArray.resize(i);
1022 while (rNodeStack.size() > nElementCount)
1024 auto pNode = rNodeStack.pop_front();
1025 aRelationArray[--i] = pNode.release();
1026 if (i > 1 && rNodeStack.size() > 1)
1027 aRelationArray[--i] = new SmGlyphSpecialNode(aToken);
1030 SmToken aDummy;
1031 SmStructureNode *pBody = new SmExpressionNode(aDummy);
1032 pBody->SetSubNodes(aRelationArray);
1035 pSNode->SetSubNodes(pLeft,pBody,pRight);
1036 pSNode->SetScaleMode(SCALE_HEIGHT);
1037 GetSmImport().GetNodeStack().push_front(pSNode);
1043 class SmXMLErrorContext_Impl : public SmXMLRowContext_Impl
1045 public:
1046 SmXMLErrorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1047 const OUString& rLName)
1048 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1050 void EndElement() SAL_OVERRIDE;
1053 void SmXMLErrorContext_Impl::EndElement()
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.
1062 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1063 while (rNodeStack.size() > nElementCount)
1065 rNodeStack.pop_front();
1071 class SmXMLNumberContext_Impl : public SmXMLImportContext
1073 protected:
1074 SmToken aToken;
1076 public:
1077 SmXMLNumberContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1078 const OUString& rLName)
1079 : SmXMLImportContext(rImport,nPrefix,rLName)
1081 aToken.cMathChar = '\0';
1082 aToken.nLevel = 5;
1083 aToken.eType = TNUMBER;
1086 virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
1088 void EndElement() SAL_OVERRIDE;
1091 void SmXMLNumberContext_Impl::TCharacters(const OUString &rChars)
1093 aToken.aText = rChars;
1096 void SmXMLNumberContext_Impl::EndElement()
1098 GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_NUMBER));
1103 class SmXMLAnnotationContext_Impl : public SmXMLImportContext
1105 bool bIsStarMath;
1107 public:
1108 SmXMLAnnotationContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1109 const OUString& rLName)
1110 : SmXMLImportContext(rImport,nPrefix,rLName), bIsStarMath(false) {}
1112 virtual void Characters(const OUString &rChars) SAL_OVERRIDE;
1114 void StartElement(const uno::Reference<xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE;
1117 void SmXMLAnnotationContext_Impl::StartElement(const uno::Reference<
1118 xml::sax::XAttributeList > & xAttrList )
1120 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1121 for (sal_Int16 i=0;i<nAttrCount;i++)
1123 OUString sAttrName = xAttrList->getNameByIndex(i);
1124 OUString aLocalName;
1125 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
1126 GetKeyByAttrName(sAttrName,&aLocalName);
1128 OUString sValue = xAttrList->getValueByIndex(i);
1129 const SvXMLTokenMap &rAttrTokenMap =
1130 GetSmImport().GetAnnotationAttrTokenMap();
1131 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
1133 case XML_TOK_ENCODING:
1134 bIsStarMath= sValue == "StarMath 5.0";
1135 break;
1136 default:
1137 break;
1142 void SmXMLAnnotationContext_Impl::Characters(const OUString &rChars)
1144 if (bIsStarMath)
1145 GetSmImport().SetText( GetSmImport().GetText() + rChars );
1150 class SmXMLTextContext_Impl : public SmXMLImportContext
1152 protected:
1153 SmToken aToken;
1155 public:
1156 SmXMLTextContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1157 const OUString& rLName)
1158 : SmXMLImportContext(rImport,nPrefix,rLName)
1160 aToken.cMathChar = '\0';
1161 aToken.nLevel = 5;
1162 aToken.eType = TTEXT;
1165 virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
1167 void EndElement() SAL_OVERRIDE;
1170 void SmXMLTextContext_Impl::TCharacters(const OUString &rChars)
1172 aToken.aText = rChars;
1175 void SmXMLTextContext_Impl::EndElement()
1177 GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_TEXT));
1182 class SmXMLStringContext_Impl : public SmXMLImportContext
1184 protected:
1185 SmToken aToken;
1187 public:
1188 SmXMLStringContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1189 const OUString& rLName)
1190 : SmXMLImportContext(rImport,nPrefix,rLName)
1192 aToken.cMathChar = '\0';
1193 aToken.nLevel = 5;
1194 aToken.eType = TTEXT;
1197 virtual void TCharacters(const OUString &rChars) SAL_OVERRIDE;
1199 void EndElement() SAL_OVERRIDE;
1202 void SmXMLStringContext_Impl::TCharacters(const OUString &rChars)
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 \"".
1212 Obviously this isn't fully done here.
1214 aToken.aText = "\"" + rChars + "\"";
1217 void SmXMLStringContext_Impl::EndElement()
1219 GetSmImport().GetNodeStack().push_front(new SmTextNode(aToken,FNT_FIXED));
1224 class SmXMLIdentifierContext_Impl : public SmXMLImportContext
1226 protected:
1227 SmXMLContext_Helper aStyleHelper;
1228 SmToken aToken;
1230 public:
1231 SmXMLIdentifierContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1232 const OUString& rLName)
1233 : SmXMLImportContext(rImport,nPrefix,rLName),aStyleHelper(*this)
1235 aToken.cMathChar = '\0';
1236 aToken.nLevel = 5;
1237 aToken.eType = TIDENT;
1240 void TCharacters(const OUString &rChars) SAL_OVERRIDE;
1241 void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList ) SAL_OVERRIDE
1243 aStyleHelper.RetrieveAttrs(xAttrList);
1245 void EndElement() SAL_OVERRIDE;
1248 void SmXMLIdentifierContext_Impl::EndElement()
1250 SmTextNode *pNode = 0;
1251 //we will handle identifier italic/normal here instead of with a standalone
1252 //font node
1253 if (((aStyleHelper.nIsItalic == -1) && (aToken.aText.getLength() > 1))
1254 || ((aStyleHelper.nIsItalic == 0) && (aToken.aText.getLength() == 1)))
1256 pNode = new SmTextNode(aToken,FNT_FUNCTION);
1257 pNode->GetFont().SetItalic(ITALIC_NONE);
1258 aStyleHelper.nIsItalic = -1;
1260 else
1261 pNode = new SmTextNode(aToken,FNT_VARIABLE);
1262 if (aStyleHelper.bFontNodeNeeded && aStyleHelper.nIsItalic != -1)
1264 if (aStyleHelper.nIsItalic)
1265 pNode->GetFont().SetItalic(ITALIC_NORMAL);
1266 else
1267 pNode->GetFont().SetItalic(ITALIC_NONE);
1270 if ((-1!=aStyleHelper.nIsBold) || (0.0!=aStyleHelper.nFontSize) ||
1271 (!aStyleHelper.sFontFamily.isEmpty()) ||
1272 !aStyleHelper.sColor.isEmpty())
1273 aStyleHelper.bFontNodeNeeded=true;
1274 else
1275 aStyleHelper.bFontNodeNeeded=false;
1276 if (aStyleHelper.bFontNodeNeeded)
1277 aStyleHelper.ApplyAttrs();
1278 GetSmImport().GetNodeStack().push_front(pNode);
1281 void SmXMLIdentifierContext_Impl::TCharacters(const OUString &rChars)
1283 aToken.aText = rChars;
1288 class SmXMLOperatorContext_Impl : public SmXMLImportContext
1290 bool bIsStretchy;
1292 protected:
1293 SmToken aToken;
1295 public:
1296 SmXMLOperatorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1297 const OUString& rLName)
1298 : SmXMLImportContext(rImport,nPrefix,rLName), bIsStretchy(false)
1300 aToken.eType = TSPECIAL;
1301 aToken.nLevel = 5;
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;
1309 void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
1311 aToken.cMathChar = rChars[0];
1314 void SmXMLOperatorContext_Impl::EndElement()
1316 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 if (bIsStretchy)
1321 pNode->SetScaleMode(SCALE_HEIGHT);
1322 GetSmImport().GetNodeStack().push_front(pNode);
1327 void SmXMLOperatorContext_Impl::StartElement(const uno::Reference<
1328 xml::sax::XAttributeList > & xAttrList )
1330 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1331 for (sal_Int16 i=0;i<nAttrCount;i++)
1333 OUString sAttrName = xAttrList->getNameByIndex(i);
1334 OUString aLocalName;
1335 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
1336 GetKeyByAttrName(sAttrName,&aLocalName);
1338 OUString sValue = xAttrList->getValueByIndex(i);
1339 const SvXMLTokenMap &rAttrTokenMap =
1340 GetSmImport().GetOperatorAttrTokenMap();
1341 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
1343 case XML_TOK_STRETCHY:
1344 bIsStretchy = sValue.equals(
1345 GetXMLToken(XML_TRUE));
1346 break;
1347 default:
1348 break;
1356 class SmXMLSpaceContext_Impl : public SmXMLImportContext
1358 public:
1359 SmXMLSpaceContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1360 const OUString& rLName)
1361 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1363 void StartElement(const uno::Reference< xml::sax::XAttributeList >& xAttrList ) SAL_OVERRIDE;
1366 void SmXMLSpaceContext_Impl::StartElement(
1367 const uno::Reference<xml::sax::XAttributeList > & /*xAttrList*/ )
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 SmToken aToken;
1372 aToken.cMathChar = '\0';
1373 aToken.eType = TBLANK;
1374 aToken.nLevel = 5;
1375 SmBlankNode *pBlank = new SmBlankNode(aToken);
1376 pBlank->IncreaseBy(aToken);
1377 GetSmImport().GetNodeStack().push_front(pBlank);
1382 class SmXMLSubContext_Impl : public SmXMLRowContext_Impl
1384 protected:
1385 void GenericEndElement(SmTokenType eType,SmSubSup aSubSup);
1387 public:
1388 SmXMLSubContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1389 const OUString& rLName)
1390 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1392 void EndElement() SAL_OVERRIDE
1394 GenericEndElement(TRSUB,RSUB);
1399 void SmXMLSubContext_Impl::GenericEndElement(SmTokenType eType, SmSubSup eSubSup)
1401 /*The <msub> element requires exactly 2 arguments.*/
1402 const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
1403 OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
1404 if (!bNodeCheck)
1405 return;
1407 SmToken aToken;
1408 aToken.cMathChar = '\0';
1409 aToken.eType = eType;
1410 SmSubSupNode *pNode = new SmSubSupNode(aToken);
1411 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1413 // initialize subnodes array
1414 SmNodeArray aSubNodes;
1415 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
1416 for (size_t i = 1; i < aSubNodes.size(); i++)
1417 aSubNodes[i] = NULL;
1419 aSubNodes[eSubSup+1] = popOrZero(rNodeStack);
1420 aSubNodes[0] = popOrZero(rNodeStack);
1421 pNode->SetSubNodes(aSubNodes);
1422 rNodeStack.push_front(pNode);
1427 class SmXMLSupContext_Impl : public SmXMLSubContext_Impl
1429 public:
1430 SmXMLSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1431 const OUString& rLName)
1432 : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
1434 void EndElement() SAL_OVERRIDE
1436 GenericEndElement(TRSUP,RSUP);
1442 class SmXMLSubSupContext_Impl : public SmXMLRowContext_Impl
1444 protected:
1445 void GenericEndElement(SmTokenType eType, SmSubSup aSub,SmSubSup aSup);
1447 public:
1448 SmXMLSubSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1449 const OUString& rLName)
1450 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1452 void EndElement() SAL_OVERRIDE
1454 GenericEndElement(TRSUB,RSUB,RSUP);
1458 void SmXMLSubSupContext_Impl::GenericEndElement(SmTokenType eType,
1459 SmSubSup aSub,SmSubSup aSup)
1461 /*The <msub> element requires exactly 3 arguments.*/
1462 const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 3;
1463 OSL_ENSURE( bNodeCheck, "SubSup has not three arguments" );
1464 if (!bNodeCheck)
1465 return;
1467 SmToken aToken;
1468 aToken.cMathChar = '\0';
1469 aToken.eType = eType;
1470 SmSubSupNode *pNode = new SmSubSupNode(aToken);
1471 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1473 // initialize subnodes array
1474 SmNodeArray aSubNodes;
1475 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
1476 for (size_t i = 1; i < aSubNodes.size(); i++)
1477 aSubNodes[i] = NULL;
1479 aSubNodes[aSup+1] = popOrZero(rNodeStack);
1480 aSubNodes[aSub+1] = popOrZero(rNodeStack);
1481 aSubNodes[0] = popOrZero(rNodeStack);
1482 pNode->SetSubNodes(aSubNodes);
1483 rNodeStack.push_front(pNode);
1488 class SmXMLUnderContext_Impl : public SmXMLSubContext_Impl
1490 protected:
1491 sal_Int16 nAttrCount;
1493 public:
1494 SmXMLUnderContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1495 const OUString& rLName)
1496 : SmXMLSubContext_Impl(rImport,nPrefix,rLName)
1497 , nAttrCount( 0 )
1500 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
1501 void EndElement() SAL_OVERRIDE;
1502 void HandleAccent();
1505 void SmXMLUnderContext_Impl::StartElement(const uno::Reference<
1506 xml::sax::XAttributeList > & xAttrList )
1508 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1511 void SmXMLUnderContext_Impl::HandleAccent()
1513 const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
1514 OSL_ENSURE( bNodeCheck, "Sub has not two arguments" );
1515 if (!bNodeCheck)
1516 return;
1518 /*Just one special case for the underline thing*/
1519 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1520 SmNode *pTest = popOrZero(rNodeStack);
1521 SmToken aToken;
1522 aToken.cMathChar = '\0';
1523 aToken.eType = TUNDERLINE;
1526 SmNodeArray aSubNodes;
1527 aSubNodes.resize(2);
1529 SmStructureNode *pNode = new SmAttributNode(aToken);
1530 if ((pTest->GetToken().cMathChar & 0x0FFF) == 0x0332)
1532 aSubNodes[0] = new SmRectangleNode(aToken);
1533 delete pTest;
1535 else
1536 aSubNodes[0] = pTest;
1538 aSubNodes[1] = popOrZero(rNodeStack);
1539 pNode->SetSubNodes(aSubNodes);
1540 pNode->SetScaleMode(SCALE_WIDTH);
1541 rNodeStack.push_front(pNode);
1545 void SmXMLUnderContext_Impl::EndElement()
1547 if (!nAttrCount)
1548 GenericEndElement(TCSUB,CSUB);
1549 else
1550 HandleAccent();
1555 class SmXMLOverContext_Impl : public SmXMLSubContext_Impl
1557 protected:
1558 sal_Int16 nAttrCount;
1560 public:
1561 SmXMLOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1562 const OUString& rLName)
1563 : SmXMLSubContext_Impl(rImport,nPrefix,rLName), nAttrCount(0) {}
1565 void EndElement() SAL_OVERRIDE;
1566 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList ) SAL_OVERRIDE;
1567 void HandleAccent();
1571 void SmXMLOverContext_Impl::StartElement(const uno::Reference<
1572 xml::sax::XAttributeList > & xAttrList )
1574 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1578 void SmXMLOverContext_Impl::EndElement()
1580 if (!nAttrCount)
1581 GenericEndElement(TCSUP,CSUP);
1582 else
1583 HandleAccent();
1587 void SmXMLOverContext_Impl::HandleAccent()
1589 const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
1590 OSL_ENSURE (bNodeCheck, "Sub has not two arguments");
1591 if (!bNodeCheck)
1592 return;
1594 SmToken aToken;
1595 aToken.cMathChar = '\0';
1596 aToken.eType = TACUTE;
1598 SmAttributNode *pNode = new SmAttributNode(aToken);
1599 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1601 SmNodeArray aSubNodes;
1602 aSubNodes.resize(2);
1603 aSubNodes[0] = popOrZero(rNodeStack);
1604 aSubNodes[1] = popOrZero(rNodeStack);
1605 pNode->SetSubNodes(aSubNodes);
1606 pNode->SetScaleMode(SCALE_WIDTH);
1607 rNodeStack.push_front(pNode);
1613 class SmXMLUnderOverContext_Impl : public SmXMLSubSupContext_Impl
1615 public:
1616 SmXMLUnderOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1617 const OUString& rLName)
1618 : SmXMLSubSupContext_Impl(rImport,nPrefix,rLName) {}
1620 void EndElement() SAL_OVERRIDE
1622 GenericEndElement(TCSUB,CSUB,CSUP);
1628 class SmXMLMultiScriptsContext_Impl : public SmXMLSubSupContext_Impl
1630 bool bHasPrescripts;
1632 void ProcessSubSupPairs(bool bIsPrescript);
1634 public:
1635 SmXMLMultiScriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1636 const OUString& rLName) :
1637 SmXMLSubSupContext_Impl(rImport,nPrefix,rLName),
1638 bHasPrescripts(false) {}
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;
1648 class SmXMLNoneContext_Impl : public SmXMLImportContext
1650 public:
1651 SmXMLNoneContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1652 const OUString& rLName)
1653 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1655 void EndElement() SAL_OVERRIDE;
1659 void SmXMLNoneContext_Impl::EndElement()
1661 SmToken aToken;
1662 aToken.cMathChar = '\0';
1663 aToken.aText.clear();
1664 aToken.nLevel = 5;
1665 aToken.eType = TIDENT;
1666 GetSmImport().GetNodeStack().push_front(
1667 new SmTextNode(aToken,FNT_VARIABLE));
1672 class SmXMLPrescriptsContext_Impl : public SmXMLImportContext
1674 public:
1675 SmXMLPrescriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1676 const OUString& rLName)
1677 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1682 class SmXMLTableRowContext_Impl : public SmXMLRowContext_Impl
1684 public:
1685 SmXMLTableRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1686 const OUString& rLName) :
1687 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1690 SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
1691 const OUString& rLocalName,
1692 const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
1698 class SmXMLTableContext_Impl : public SmXMLTableRowContext_Impl
1700 public:
1701 SmXMLTableContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1702 const OUString& rLName) :
1703 SmXMLTableRowContext_Impl(rImport,nPrefix,rLName)
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;
1715 class SmXMLTableCellContext_Impl : public SmXMLRowContext_Impl
1717 public:
1718 SmXMLTableCellContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1719 const OUString& rLName) :
1720 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1726 class SmXMLAlignGroupContext_Impl : public SmXMLRowContext_Impl
1728 public:
1729 SmXMLAlignGroupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1730 const OUString& rLName) :
1731 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1734 /*Don't do anything with alignment for now*/
1735 void EndElement() SAL_OVERRIDE
1742 class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
1744 size_t mnSelection; // 1-based
1746 public:
1747 SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1748 const OUString& rLName) :
1749 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1750 , mnSelection(1)
1753 void StartElement(const uno::Reference<xml::sax::XAttributeList> &xAttrList) SAL_OVERRIDE;
1754 void EndElement() SAL_OVERRIDE;
1759 // NB: virtually inherit so we can multiply inherit properly
1760 // in SmXMLFlatDocContext_Impl
1761 class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext
1763 public:
1764 SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
1765 const OUString& rLName)
1766 : SvXMLImportContext(rImport,nPrfx,rLName) {}
1768 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList) SAL_OVERRIDE;
1771 SvXMLImportContext *SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
1772 const OUString& rLocalName,
1773 const uno::Reference< xml::sax::XAttributeList > &xAttrList)
1775 SvXMLImportContext *pContext = 0;
1776 if ( XML_NAMESPACE_OFFICE == nPrefix &&
1777 rLocalName == GetXMLToken(XML_META) )
1779 SAL_WARN("starmath", "XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
1781 else if ( XML_NAMESPACE_OFFICE == nPrefix &&
1782 rLocalName == GetXMLToken(XML_SETTINGS) )
1784 pContext = new XMLDocumentSettingsContext( GetImport(),
1785 XML_NAMESPACE_OFFICE, rLocalName,
1786 xAttrList );
1788 else
1789 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1791 return pContext;
1796 // context for flat file xml format
1797 class SmXMLFlatDocContext_Impl
1798 : public SmXMLOfficeContext_Impl, public SvXMLMetaDocumentContext
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);
1805 virtual ~SmXMLFlatDocContext_Impl();
1807 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList) SAL_OVERRIDE;
1810 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 i_xDocProps)
1820 SmXMLFlatDocContext_Impl::~SmXMLFlatDocContext_Impl()
1824 SvXMLImportContext *SmXMLFlatDocContext_Impl::CreateChildContext(
1825 sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
1826 const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
1828 // behave like meta base class iff we encounter office:meta
1829 if ( XML_NAMESPACE_OFFICE == i_nPrefix &&
1830 i_rLocalName == GetXMLToken(XML_META) )
1832 return SvXMLMetaDocumentContext::CreateChildContext(
1833 i_nPrefix, i_rLocalName, i_xAttrList );
1835 else
1837 return SmXMLOfficeContext_Impl::CreateChildContext(
1838 i_nPrefix, i_rLocalName, i_xAttrList );
1844 static const SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
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
1870 static const SvXMLTokenMapEntry aPresLayoutAttrTokenMap[] =
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
1881 static const SvXMLTokenMapEntry aFencedAttrTokenMap[] =
1883 { XML_NAMESPACE_MATH, XML_OPEN, XML_TOK_OPEN },
1884 { XML_NAMESPACE_MATH, XML_CLOSE, XML_TOK_CLOSE },
1885 XML_TOKEN_MAP_END
1888 static const SvXMLTokenMapEntry aOperatorAttrTokenMap[] =
1890 { XML_NAMESPACE_MATH, XML_STRETCHY, XML_TOK_STRETCHY },
1891 XML_TOKEN_MAP_END
1894 static const SvXMLTokenMapEntry aAnnotationAttrTokenMap[] =
1896 { XML_NAMESPACE_MATH, XML_ENCODING, XML_TOK_ENCODING },
1897 XML_TOKEN_MAP_END
1901 static const SvXMLTokenMapEntry aPresElemTokenMap[] =
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
1914 static const SvXMLTokenMapEntry aPresScriptEmptyElemTokenMap[] =
1916 { XML_NAMESPACE_MATH, XML_MPRESCRIPTS, XML_TOK_MPRESCRIPTS },
1917 { XML_NAMESPACE_MATH, XML_NONE, XML_TOK_NONE },
1918 XML_TOKEN_MAP_END
1921 static const SvXMLTokenMapEntry aPresTableElemTokenMap[] =
1923 { XML_NAMESPACE_MATH, XML_MTR, XML_TOK_MTR },
1924 { XML_NAMESPACE_MATH, XML_MTD, XML_TOK_MTD },
1925 XML_TOKEN_MAP_END
1928 static const SvXMLTokenMapEntry aColorTokenMap[] =
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
1949 static const SvXMLTokenMapEntry aActionAttrTokenMap[] =
1951 { XML_NAMESPACE_MATH, XML_SELECTION, XML_TOK_SELECTION },
1952 XML_TOKEN_MAP_END
1956 const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
1958 if (!pPresLayoutElemTokenMap)
1959 pPresLayoutElemTokenMap.reset(new SvXMLTokenMap(aPresLayoutElemTokenMap));
1960 return *pPresLayoutElemTokenMap;
1963 const SvXMLTokenMap& SmXMLImport::GetPresLayoutAttrTokenMap()
1965 if (!pPresLayoutAttrTokenMap)
1966 pPresLayoutAttrTokenMap.reset(new SvXMLTokenMap(aPresLayoutAttrTokenMap));
1967 return *pPresLayoutAttrTokenMap;
1971 const SvXMLTokenMap& SmXMLImport::GetFencedAttrTokenMap()
1973 if (!pFencedAttrTokenMap)
1974 pFencedAttrTokenMap.reset(new SvXMLTokenMap(aFencedAttrTokenMap));
1975 return *pFencedAttrTokenMap;
1978 const SvXMLTokenMap& SmXMLImport::GetOperatorAttrTokenMap()
1980 if (!pOperatorAttrTokenMap)
1981 pOperatorAttrTokenMap.reset(new SvXMLTokenMap(aOperatorAttrTokenMap));
1982 return *pOperatorAttrTokenMap;
1985 const SvXMLTokenMap& SmXMLImport::GetAnnotationAttrTokenMap()
1987 if (!pAnnotationAttrTokenMap)
1988 pAnnotationAttrTokenMap.reset(new SvXMLTokenMap(aAnnotationAttrTokenMap));
1989 return *pAnnotationAttrTokenMap;
1992 const SvXMLTokenMap& SmXMLImport::GetPresElemTokenMap()
1994 if (!pPresElemTokenMap)
1995 pPresElemTokenMap.reset(new SvXMLTokenMap(aPresElemTokenMap));
1996 return *pPresElemTokenMap;
1999 const SvXMLTokenMap& SmXMLImport::GetPresScriptEmptyElemTokenMap()
2001 if (!pPresScriptEmptyElemTokenMap)
2002 pPresScriptEmptyElemTokenMap.reset(new
2003 SvXMLTokenMap(aPresScriptEmptyElemTokenMap));
2004 return *pPresScriptEmptyElemTokenMap;
2007 const SvXMLTokenMap& SmXMLImport::GetPresTableElemTokenMap()
2009 if (!pPresTableElemTokenMap)
2010 pPresTableElemTokenMap.reset(new SvXMLTokenMap(aPresTableElemTokenMap));
2011 return *pPresTableElemTokenMap;
2014 const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
2016 if (!pColorTokenMap)
2017 pColorTokenMap.reset(new SvXMLTokenMap(aColorTokenMap));
2018 return *pColorTokenMap;
2021 const SvXMLTokenMap& SmXMLImport::GetActionAttrTokenMap()
2023 if (!pActionAttrTokenMap)
2024 pActionAttrTokenMap.reset(new SvXMLTokenMap(aActionAttrTokenMap));
2025 return *pActionAttrTokenMap;
2029 SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
2030 sal_uInt16 nPrefix,
2031 const OUString& rLocalName,
2032 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2034 SvXMLImportContext* pContext = 0L;
2036 const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresLayoutElemTokenMap();
2038 switch(rTokenMap.Get(nPrefix, rLocalName))
2040 //Consider semantics a dummy except for any starmath annotations
2041 case XML_TOK_SEMANTICS:
2042 pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
2043 xAttrList);
2044 break;
2045 /*General Layout Schemata*/
2046 case XML_TOK_MROW:
2047 pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
2048 xAttrList);
2049 break;
2050 case XML_TOK_MENCLOSE:
2051 pContext = GetSmImport().CreateEncloseContext(nPrefix,rLocalName,
2052 xAttrList);
2053 break;
2054 case XML_TOK_MFRAC:
2055 pContext = GetSmImport().CreateFracContext(nPrefix,rLocalName,
2056 xAttrList);
2057 break;
2058 case XML_TOK_MSQRT:
2059 pContext = GetSmImport().CreateSqrtContext(nPrefix,rLocalName,
2060 xAttrList);
2061 break;
2062 case XML_TOK_MROOT:
2063 pContext = GetSmImport().CreateRootContext(nPrefix,rLocalName,
2064 xAttrList);
2065 break;
2066 case XML_TOK_MSTYLE:
2067 pContext = GetSmImport().CreateStyleContext(nPrefix,rLocalName,
2068 xAttrList);
2069 break;
2070 case XML_TOK_MERROR:
2071 pContext = GetSmImport().CreateErrorContext(nPrefix,rLocalName,
2072 xAttrList);
2073 break;
2074 case XML_TOK_MPADDED:
2075 pContext = GetSmImport().CreatePaddedContext(nPrefix,rLocalName,
2076 xAttrList);
2077 break;
2078 case XML_TOK_MPHANTOM:
2079 pContext = GetSmImport().CreatePhantomContext(nPrefix,rLocalName,
2080 xAttrList);
2081 break;
2082 case XML_TOK_MFENCED:
2083 pContext = GetSmImport().CreateFencedContext(nPrefix,rLocalName,
2084 xAttrList);
2085 break;
2086 /*Script and Limit Schemata*/
2087 case XML_TOK_MSUB:
2088 pContext = GetSmImport().CreateSubContext(nPrefix,rLocalName,
2089 xAttrList);
2090 break;
2091 case XML_TOK_MSUP:
2092 pContext = GetSmImport().CreateSupContext(nPrefix,rLocalName,
2093 xAttrList);
2094 break;
2095 case XML_TOK_MSUBSUP:
2096 pContext = GetSmImport().CreateSubSupContext(nPrefix,rLocalName,
2097 xAttrList);
2098 break;
2099 case XML_TOK_MUNDER:
2100 pContext = GetSmImport().CreateUnderContext(nPrefix,rLocalName,
2101 xAttrList);
2102 break;
2103 case XML_TOK_MOVER:
2104 pContext = GetSmImport().CreateOverContext(nPrefix,rLocalName,
2105 xAttrList);
2106 break;
2107 case XML_TOK_MUNDEROVER:
2108 pContext = GetSmImport().CreateUnderOverContext(nPrefix,rLocalName,
2109 xAttrList);
2110 break;
2111 case XML_TOK_MMULTISCRIPTS:
2112 pContext = GetSmImport().CreateMultiScriptsContext(nPrefix,
2113 rLocalName, xAttrList);
2114 break;
2115 case XML_TOK_MTABLE:
2116 pContext = GetSmImport().CreateTableContext(nPrefix,
2117 rLocalName, xAttrList);
2118 break;
2119 case XML_TOK_MACTION:
2120 pContext = GetSmImport().CreateActionContext(nPrefix,
2121 rLocalName, xAttrList);
2122 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 SmXMLRowContext_Impl aTempContext(GetSmImport(),nPrefix,
2128 GetXMLToken(XML_MROW));
2130 pContext = aTempContext.StrictCreateChildContext(nPrefix,
2131 rLocalName, xAttrList);
2132 break;
2134 return pContext;
2137 void SmXMLDocContext_Impl::EndElement()
2139 SmNodeArray ContextArray;
2140 ContextArray.resize(1);
2141 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2143 ContextArray[0] = popOrZero(rNodeStack);
2145 SmToken aDummy;
2146 SmStructureNode *pSNode = new SmLineNode(aDummy);
2147 pSNode->SetSubNodes(ContextArray);
2148 rNodeStack.push_front(pSNode);
2150 SmNodeArray LineArray;
2151 auto n = rNodeStack.size();
2152 LineArray.resize(n);
2153 for (size_t j = 0; j < n; j++)
2155 auto pNode = rNodeStack.pop_front();
2156 LineArray[n - (j + 1)] = pNode.release();
2158 SmStructureNode *pSNode2 = new SmTableNode(aDummy);
2159 pSNode2->SetSubNodes(LineArray);
2160 rNodeStack.push_front(pSNode2);
2163 void SmXMLFracContext_Impl::EndElement()
2165 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2166 const bool bNodeCheck = rNodeStack.size() - nElementCount == 2;
2167 OSL_ENSURE( bNodeCheck, "Fraction (mfrac) tag is missing component" );
2168 if (!bNodeCheck)
2169 return;
2171 SmToken aToken;
2172 aToken.cMathChar = '\0';
2173 aToken.eType = TOVER;
2174 SmStructureNode *pSNode = new SmBinVerNode(aToken);
2175 SmNode *pOper = new SmRectangleNode(aToken);
2176 SmNode *pSecond = popOrZero(rNodeStack);
2177 SmNode *pFirst = popOrZero(rNodeStack);
2178 pSNode->SetSubNodes(pFirst,pOper,pSecond);
2179 rNodeStack.push_front(pSNode);
2182 void SmXMLRootContext_Impl::EndElement()
2184 /*The <mroot> element requires exactly 2 arguments.*/
2185 const bool bNodeCheck = GetSmImport().GetNodeStack().size() - nElementCount == 2;
2186 OSL_ENSURE( bNodeCheck, "Root tag is missing component");
2187 if (!bNodeCheck)
2188 return;
2190 SmToken aToken;
2191 aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
2192 aToken.eType = TNROOT;
2193 SmStructureNode *pSNode = new SmRootNode(aToken);
2194 SmNode *pOper = new SmRootSymbolNode(aToken);
2195 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2196 SmNode *pIndex = popOrZero(rNodeStack);
2197 SmNode *pBase = popOrZero(rNodeStack);
2198 pSNode->SetSubNodes(pIndex,pOper,pBase);
2199 rNodeStack.push_front(pSNode);
2202 void SmXMLSqrtContext_Impl::EndElement()
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
2209 if (GetSmImport().GetNodeStack().size() - nElementCount > 1)
2210 SmXMLRowContext_Impl::EndElement();
2212 SmToken aToken;
2213 aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
2214 aToken.eType = TSQRT;
2215 SmStructureNode *pSNode = new SmRootNode(aToken);
2216 SmNode *pOper = new SmRootSymbolNode(aToken);
2217 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2218 pSNode->SetSubNodes(0,pOper,popOrZero(rNodeStack));
2219 rNodeStack.push_front(pSNode);
2222 void SmXMLRowContext_Impl::EndElement()
2224 SmNodeArray aRelationArray;
2225 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2227 if (rNodeStack.size() > nElementCount)
2229 auto nSize = rNodeStack.size() - nElementCount;
2231 aRelationArray.resize(nSize);
2232 for (auto j=nSize;j > 0;j--)
2234 auto pNode = rNodeStack.pop_front();
2235 aRelationArray[j-1] = pNode.release();
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 if (((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
2244 && (aRelationArray[0]->GetType() == NMATH))
2245 || ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
2246 && (aRelationArray[nSize-1]->GetType() == NMATH)))
2248 SmToken aToken;
2249 aToken.cMathChar = '\0';
2250 aToken.nLevel = 5;
2252 int nLeft=0,nRight=0;
2253 if ((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
2254 && (aRelationArray[0]->GetType() == NMATH))
2256 aToken = aRelationArray[0]->GetToken();
2257 nLeft=1;
2259 else
2260 aToken.cMathChar = '\0';
2262 aToken.eType = TLPARENT;
2263 SmNode *pLeft = new SmMathSymbolNode(aToken);
2265 if ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
2266 && (aRelationArray[nSize-1]->GetType() == NMATH))
2268 aToken = aRelationArray[nSize-1]->GetToken();
2269 nRight=1;
2271 else
2272 aToken.cMathChar = '\0';
2274 aToken.eType = TRPARENT;
2275 SmNode *pRight = new SmMathSymbolNode(aToken);
2277 SmNodeArray aRelationArray2;
2279 //!! nSize-nLeft-nRight may be < 0 !!
2280 int nRelArrSize = nSize-nLeft-nRight;
2281 if (nRelArrSize > 0)
2283 aRelationArray2.resize(nRelArrSize);
2284 for (int i=0;i < nRelArrSize;i++)
2285 aRelationArray2[i] = aRelationArray[i+nLeft];
2288 SmToken aDummy;
2289 SmStructureNode *pSNode = new SmBraceNode(aToken);
2290 SmStructureNode *pBody = new SmExpressionNode(aDummy);
2291 pBody->SetSubNodes(aRelationArray2);
2293 pSNode->SetSubNodes(pLeft,pBody,pRight);
2294 pSNode->SetScaleMode(SCALE_HEIGHT);
2295 rNodeStack.push_front(pSNode);
2296 return;
2299 else //Multiple newlines result in empty row elements
2301 aRelationArray.resize(1);
2302 SmToken aToken;
2303 aToken.cMathChar = '\0';
2304 aToken.nLevel = 5;
2305 aToken.eType = TNEWLINE;
2306 aRelationArray[0] = new SmLineNode(aToken);
2309 SmToken aDummy;
2310 SmStructureNode *pSNode = new SmExpressionNode(aDummy);
2311 pSNode->SetSubNodes(aRelationArray);
2312 rNodeStack.push_front(pSNode);
2316 SvXMLImportContext *SmXMLRowContext_Impl::StrictCreateChildContext(
2317 sal_uInt16 nPrefix,
2318 const OUString& rLocalName,
2319 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2321 SvXMLImportContext* pContext = 0L;
2323 const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresElemTokenMap();
2324 switch(rTokenMap.Get(nPrefix, rLocalName))
2326 /*Note that these should accept malignmark subelements, but do not*/
2327 case XML_TOK_MN:
2328 pContext = GetSmImport().CreateNumberContext(nPrefix,rLocalName,
2329 xAttrList);
2330 break;
2331 case XML_TOK_MI:
2332 pContext = GetSmImport().CreateIdentifierContext(nPrefix,rLocalName,
2333 xAttrList);
2334 break;
2335 case XML_TOK_MO:
2336 pContext = GetSmImport().CreateOperatorContext(nPrefix,rLocalName,
2337 xAttrList);
2338 break;
2339 case XML_TOK_MTEXT:
2340 pContext = GetSmImport().CreateTextContext(nPrefix,rLocalName,
2341 xAttrList);
2342 break;
2343 case XML_TOK_MSPACE:
2344 pContext = GetSmImport().CreateSpaceContext(nPrefix,rLocalName,
2345 xAttrList);
2346 break;
2347 case XML_TOK_MS:
2348 pContext = GetSmImport().CreateStringContext(nPrefix,rLocalName,
2349 xAttrList);
2350 break;
2352 /*Note: The maligngroup should only be seen when the row
2353 * (or descendants) are in a table*/
2354 case XML_TOK_MALIGNGROUP:
2355 pContext = GetSmImport().CreateAlignGroupContext(nPrefix,rLocalName,
2356 xAttrList);
2357 break;
2359 case XML_TOK_ANNOTATION:
2360 pContext = GetSmImport().CreateAnnotationContext(nPrefix,rLocalName,
2361 xAttrList);
2362 break;
2364 default:
2365 break;
2367 return pContext;
2371 SvXMLImportContext *SmXMLRowContext_Impl::CreateChildContext(
2372 sal_uInt16 nPrefix,
2373 const OUString& rLocalName,
2374 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2376 SvXMLImportContext* pContext = StrictCreateChildContext(nPrefix,
2377 rLocalName, xAttrList);
2379 if (!pContext)
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 rLocalName,xAttrList);
2386 return pContext;
2390 SvXMLImportContext *SmXMLMultiScriptsContext_Impl::CreateChildContext(
2391 sal_uInt16 nPrefix,
2392 const OUString& rLocalName,
2393 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2395 SvXMLImportContext* pContext = 0L;
2397 const SvXMLTokenMap& rTokenMap = GetSmImport().
2398 GetPresScriptEmptyElemTokenMap();
2399 switch(rTokenMap.Get(nPrefix, rLocalName))
2401 case XML_TOK_MPRESCRIPTS:
2402 bHasPrescripts = true;
2403 ProcessSubSupPairs(false);
2404 pContext = GetSmImport().CreatePrescriptsContext(nPrefix,
2405 rLocalName, xAttrList);
2406 break;
2407 case XML_TOK_NONE:
2408 pContext = GetSmImport().CreateNoneContext(nPrefix,rLocalName,
2409 xAttrList);
2410 break;
2411 default:
2412 pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
2413 rLocalName,xAttrList);
2414 break;
2416 return pContext;
2419 void SmXMLMultiScriptsContext_Impl::ProcessSubSupPairs(bool bIsPrescript)
2421 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2423 if (rNodeStack.size() <= nElementCount)
2424 return;
2426 auto nCount = rNodeStack.size() - nElementCount - 1;
2427 if (nCount == 0)
2428 return;
2430 if (nCount % 2 == 0)
2432 SmToken aToken;
2433 aToken.cMathChar = '\0';
2434 aToken.eType = bIsPrescript ? TLSUB : TRSUB;
2436 SmNodeStack aReverseStack;
2437 for (size_t i = 0; i < nCount + 1; i++)
2439 auto pNode = rNodeStack.pop_front();
2440 aReverseStack.push_front(pNode.release());
2443 SmSubSup eSub = bIsPrescript ? LSUB : RSUB;
2444 SmSubSup eSup = bIsPrescript ? LSUP : RSUP;
2446 for (size_t i = 0; i < nCount; i += 2)
2448 SmSubSupNode *pNode = new SmSubSupNode(aToken);
2450 // initialize subnodes array
2451 SmNodeArray aSubNodes(1 + SUBSUP_NUM_ENTRIES);
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 aSubNodes[0] = popOrZero(aReverseStack);
2458 SmNode *pScriptNode = popOrZero(aReverseStack);
2460 if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
2461 (!pScriptNode->GetToken().aText.isEmpty())))
2462 aSubNodes[eSub+1] = pScriptNode;
2463 pScriptNode = popOrZero(aReverseStack);
2464 if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
2465 (!pScriptNode->GetToken().aText.isEmpty())))
2466 aSubNodes[eSup+1] = pScriptNode;
2468 pNode->SetSubNodes(aSubNodes);
2469 aReverseStack.push_front(pNode);
2471 assert(!aReverseStack.empty());
2472 auto pNode = aReverseStack.pop_front();
2473 rNodeStack.push_front(pNode.release());
2475 else
2477 // Ignore odd number of elements.
2478 for (size_t i = 0; i < nCount; i++)
2480 rNodeStack.pop_front();
2486 void SmXMLTableContext_Impl::EndElement()
2488 SmNodeArray aExpressionArray;
2489 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2490 SmNodeStack aReverseStack;
2491 aExpressionArray.resize(rNodeStack.size()-nElementCount);
2493 auto nRows = rNodeStack.size()-nElementCount;
2494 sal_uInt16 nCols = 0;
2496 SmStructureNode *pArray;
2497 for (auto i=nRows;i > 0;i--)
2499 auto pNode = rNodeStack.pop_front();
2500 pArray = static_cast<SmStructureNode *>(pNode.release());
2501 if (pArray->GetNumSubNodes() == 0)
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
2511 SmNodeArray aRelationArray;
2512 aRelationArray.resize(1);
2513 aRelationArray[0] = pArray;
2514 SmToken aDummy;
2515 pArray = new SmExpressionNode(aDummy);
2516 pArray->SetSubNodes(aRelationArray);
2519 if (pArray->GetNumSubNodes() > nCols)
2520 nCols = pArray->GetNumSubNodes();
2521 aReverseStack.push_front(pArray);
2523 aExpressionArray.resize(nCols*nRows);
2524 size_t j=0;
2525 while ( !aReverseStack.empty() )
2527 auto pNode = aReverseStack.pop_front();
2528 pArray = static_cast<SmStructureNode *>(pNode.release());
2529 for (sal_uInt16 i=0;i<pArray->GetNumSubNodes();i++)
2530 aExpressionArray[j++] = pArray->GetSubNode(i);
2533 SmToken aToken;
2534 aToken.cMathChar = '\0';
2535 aToken.nGroup = TRGROUP;
2536 aToken.eType = TMATRIX;
2537 SmMatrixNode *pSNode = new SmMatrixNode(aToken);
2538 pSNode->SetSubNodes(aExpressionArray);
2539 pSNode->SetRowCol(static_cast<sal_uInt16>(nRows),nCols);
2540 rNodeStack.push_front(pSNode);
2543 SvXMLImportContext *SmXMLTableRowContext_Impl::CreateChildContext(
2544 sal_uInt16 nPrefix,
2545 const OUString& rLocalName,
2546 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2548 SvXMLImportContext* pContext = 0L;
2550 const SvXMLTokenMap& rTokenMap = GetSmImport().
2551 GetPresTableElemTokenMap();
2552 switch(rTokenMap.Get(nPrefix, rLocalName))
2554 case XML_TOK_MTD:
2555 pContext = GetSmImport().CreateTableCellContext(nPrefix,
2556 rLocalName, xAttrList);
2557 break;
2558 default:
2559 pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
2560 rLocalName,xAttrList);
2561 break;
2563 return pContext;
2566 SvXMLImportContext *SmXMLTableContext_Impl::CreateChildContext(
2567 sal_uInt16 nPrefix,
2568 const OUString& rLocalName,
2569 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2571 SvXMLImportContext* pContext = 0L;
2573 const SvXMLTokenMap& rTokenMap = GetSmImport().
2574 GetPresTableElemTokenMap();
2575 switch(rTokenMap.Get(nPrefix, rLocalName))
2577 case XML_TOK_MTR:
2578 pContext = GetSmImport().CreateTableRowContext(nPrefix,rLocalName,
2579 xAttrList);
2580 break;
2581 default:
2582 pContext = SmXMLTableRowContext_Impl::CreateChildContext(nPrefix,
2583 rLocalName,xAttrList);
2584 break;
2586 return pContext;
2589 void SmXMLMultiScriptsContext_Impl::EndElement()
2591 ProcessSubSupPairs(bHasPrescripts);
2594 void SmXMLActionContext_Impl::StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)
2596 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
2597 for (sal_Int16 i=0;i<nAttrCount;i++)
2599 OUString sAttrName = xAttrList->getNameByIndex(i);
2600 OUString aLocalName;
2601 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
2602 GetKeyByAttrName(sAttrName,&aLocalName);
2604 OUString sValue = xAttrList->getValueByIndex(i);
2605 const SvXMLTokenMap &rAttrTokenMap =
2606 GetSmImport().GetActionAttrTokenMap();
2607 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
2609 case XML_TOK_SELECTION:
2611 sal_uInt32 n = sValue.toUInt32();
2612 if (n > 0) mnSelection = static_cast<size_t>(n);
2614 break;
2615 default:
2616 break;
2621 void SmXMLActionContext_Impl::EndElement()
2623 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2624 auto nSize = rNodeStack.size();
2625 if (nSize <= nElementCount) {
2626 // not compliant to maction's specification, e.g., no subexpressions
2627 return;
2629 assert(mnSelection > 0);
2630 if (nSize < nElementCount + mnSelection) {
2631 // No selected subexpression exists, which is a MathML error;
2632 // fallback to selecting the first
2633 mnSelection = 1;
2635 assert(nSize >= nElementCount + mnSelection);
2636 for (auto i=nSize-(nElementCount+mnSelection); i > 0; i--)
2638 rNodeStack.pop_front();
2640 auto pSelected = rNodeStack.pop_front();
2641 for (auto i=rNodeStack.size()-nElementCount; i > 0; i--)
2643 rNodeStack.pop_front();
2645 rNodeStack.push_front(pSelected.release());
2648 SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
2649 const OUString &rLocalName,
2650 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2652 if ( XML_NAMESPACE_OFFICE == nPrefix )
2654 if ( (IsXMLToken(rLocalName, XML_DOCUMENT) ||
2655 IsXMLToken(rLocalName, XML_DOCUMENT_META)))
2657 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
2658 GetModel(), uno::UNO_QUERY_THROW);
2659 return IsXMLToken(rLocalName, XML_DOCUMENT_META)
2660 ? new SvXMLMetaDocumentContext(*this,
2661 XML_NAMESPACE_OFFICE, rLocalName,
2662 xDPS->getDocumentProperties())
2663 // flat OpenDocument file format -- this has not been tested...
2664 : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
2665 xDPS->getDocumentProperties());
2667 else
2669 return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
2672 else
2673 return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
2676 SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
2677 const OUString &rLocalName,
2678 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2680 return new SmXMLRowContext_Impl(*this,nPrefix,rLocalName);
2683 SvXMLImportContext *SmXMLImport::CreateTextContext(sal_uInt16 nPrefix,
2684 const OUString &rLocalName,
2685 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2687 return new SmXMLTextContext_Impl(*this,nPrefix,rLocalName);
2690 SvXMLImportContext *SmXMLImport::CreateAnnotationContext(sal_uInt16 nPrefix,
2691 const OUString &rLocalName,
2692 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2694 return new SmXMLAnnotationContext_Impl(*this,nPrefix,rLocalName);
2697 SvXMLImportContext *SmXMLImport::CreateStringContext(sal_uInt16 nPrefix,
2698 const OUString &rLocalName,
2699 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2701 return new SmXMLStringContext_Impl(*this,nPrefix,rLocalName);
2704 SvXMLImportContext *SmXMLImport::CreateNumberContext(sal_uInt16 nPrefix,
2705 const OUString &rLocalName,
2706 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2708 return new SmXMLNumberContext_Impl(*this,nPrefix,rLocalName);
2711 SvXMLImportContext *SmXMLImport::CreateIdentifierContext(sal_uInt16 nPrefix,
2712 const OUString &rLocalName,
2713 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2715 return new SmXMLIdentifierContext_Impl(*this,nPrefix,rLocalName);
2718 SvXMLImportContext *SmXMLImport::CreateOperatorContext(sal_uInt16 nPrefix,
2719 const OUString &rLocalName,
2720 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2722 return new SmXMLOperatorContext_Impl(*this,nPrefix,rLocalName);
2725 SvXMLImportContext *SmXMLImport::CreateSpaceContext(sal_uInt16 nPrefix,
2726 const OUString &rLocalName,
2727 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2729 return new SmXMLSpaceContext_Impl(*this,nPrefix,rLocalName);
2733 SvXMLImportContext *SmXMLImport::CreateEncloseContext(sal_uInt16 nPrefix,
2734 const OUString &rLocalName,
2735 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2737 return new SmXMLEncloseContext_Impl(*this,nPrefix,rLocalName);
2740 SvXMLImportContext *SmXMLImport::CreateFracContext(sal_uInt16 nPrefix,
2741 const OUString &rLocalName,
2742 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2744 return new SmXMLFracContext_Impl(*this,nPrefix,rLocalName);
2747 SvXMLImportContext *SmXMLImport::CreateSqrtContext(sal_uInt16 nPrefix,
2748 const OUString &rLocalName,
2749 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2751 return new SmXMLSqrtContext_Impl(*this,nPrefix,rLocalName);
2754 SvXMLImportContext *SmXMLImport::CreateRootContext(sal_uInt16 nPrefix,
2755 const OUString &rLocalName,
2756 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2758 return new SmXMLRootContext_Impl(*this,nPrefix,rLocalName);
2761 SvXMLImportContext *SmXMLImport::CreateStyleContext(sal_uInt16 nPrefix,
2762 const OUString &rLocalName,
2763 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2765 return new SmXMLStyleContext_Impl(*this,nPrefix,rLocalName);
2768 SvXMLImportContext *SmXMLImport::CreatePaddedContext(sal_uInt16 nPrefix,
2769 const OUString &rLocalName,
2770 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2772 return new SmXMLPaddedContext_Impl(*this,nPrefix,rLocalName);
2775 SvXMLImportContext *SmXMLImport::CreatePhantomContext(sal_uInt16 nPrefix,
2776 const OUString &rLocalName,
2777 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2779 return new SmXMLPhantomContext_Impl(*this,nPrefix,rLocalName);
2782 SvXMLImportContext *SmXMLImport::CreateFencedContext(sal_uInt16 nPrefix,
2783 const OUString &rLocalName,
2784 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2786 return new SmXMLFencedContext_Impl(*this,nPrefix,rLocalName);
2789 SvXMLImportContext *SmXMLImport::CreateErrorContext(sal_uInt16 nPrefix,
2790 const OUString &rLocalName,
2791 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2793 return new SmXMLErrorContext_Impl(*this,nPrefix,rLocalName);
2796 SvXMLImportContext *SmXMLImport::CreateSubContext(sal_uInt16 nPrefix,
2797 const OUString &rLocalName,
2798 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2800 return new SmXMLSubContext_Impl(*this,nPrefix,rLocalName);
2803 SvXMLImportContext *SmXMLImport::CreateSubSupContext(sal_uInt16 nPrefix,
2804 const OUString &rLocalName,
2805 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2807 return new SmXMLSubSupContext_Impl(*this,nPrefix,rLocalName);
2810 SvXMLImportContext *SmXMLImport::CreateSupContext(sal_uInt16 nPrefix,
2811 const OUString &rLocalName,
2812 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2814 return new SmXMLSupContext_Impl(*this,nPrefix,rLocalName);
2817 SvXMLImportContext *SmXMLImport::CreateUnderContext(sal_uInt16 nPrefix,
2818 const OUString &rLocalName,
2819 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2821 return new SmXMLUnderContext_Impl(*this,nPrefix,rLocalName);
2824 SvXMLImportContext *SmXMLImport::CreateOverContext(sal_uInt16 nPrefix,
2825 const OUString &rLocalName,
2826 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2828 return new SmXMLOverContext_Impl(*this,nPrefix,rLocalName);
2831 SvXMLImportContext *SmXMLImport::CreateUnderOverContext(sal_uInt16 nPrefix,
2832 const OUString &rLocalName,
2833 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2835 return new SmXMLUnderOverContext_Impl(*this,nPrefix,rLocalName);
2838 SvXMLImportContext *SmXMLImport::CreateMultiScriptsContext(sal_uInt16 nPrefix,
2839 const OUString &rLocalName,
2840 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2842 return new SmXMLMultiScriptsContext_Impl(*this,nPrefix,rLocalName);
2845 SvXMLImportContext *SmXMLImport::CreateTableContext(sal_uInt16 nPrefix,
2846 const OUString &rLocalName,
2847 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2849 return new SmXMLTableContext_Impl(*this,nPrefix,rLocalName);
2851 SvXMLImportContext *SmXMLImport::CreateTableRowContext(sal_uInt16 nPrefix,
2852 const OUString &rLocalName,
2853 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2855 return new SmXMLTableRowContext_Impl(*this,nPrefix,rLocalName);
2857 SvXMLImportContext *SmXMLImport::CreateTableCellContext(sal_uInt16 nPrefix,
2858 const OUString &rLocalName,
2859 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2861 return new SmXMLTableCellContext_Impl(*this,nPrefix,rLocalName);
2864 SvXMLImportContext *SmXMLImport::CreateNoneContext(sal_uInt16 nPrefix,
2865 const OUString &rLocalName,
2866 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2868 return new SmXMLNoneContext_Impl(*this,nPrefix,rLocalName);
2871 SvXMLImportContext *SmXMLImport::CreatePrescriptsContext(sal_uInt16 nPrefix,
2872 const OUString &rLocalName,
2873 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2875 return new SmXMLPrescriptsContext_Impl(*this,nPrefix,rLocalName);
2878 SvXMLImportContext *SmXMLImport::CreateAlignGroupContext(sal_uInt16 nPrefix,
2879 const OUString &rLocalName,
2880 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2882 return new SmXMLAlignGroupContext_Impl(*this,nPrefix,rLocalName);
2885 SvXMLImportContext *SmXMLImport::CreateActionContext(sal_uInt16 nPrefix,
2886 const OUString &rLocalName,
2887 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2889 return new SmXMLActionContext_Impl(*this,nPrefix,rLocalName);
2892 SmXMLImport::~SmXMLImport() throw ()
2896 void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
2898 uno::Reference <frame::XModel> xModel = GetModel();
2899 if ( !xModel.is() )
2900 return;
2902 uno::Reference <lang::XUnoTunnel> xTunnel;
2903 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
2904 SmModel *pModel = reinterpret_cast<SmModel *>
2905 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
2907 if ( !pModel )
2908 return;
2910 SmDocShell *pDocShell =
2911 static_cast<SmDocShell*>(pModel->GetObjectShell());
2912 if ( !pDocShell )
2913 return;
2915 Rectangle aRect( pDocShell->GetVisArea() );
2917 sal_Int32 nCount = aViewProps.getLength();
2918 const PropertyValue *pValue = aViewProps.getConstArray();
2920 long nTmp = 0;
2922 for (sal_Int32 i = 0; i < nCount ; i++)
2924 if (pValue->Name == "ViewAreaTop" )
2926 pValue->Value >>= nTmp;
2927 aRect.setY( nTmp );
2929 else if (pValue->Name == "ViewAreaLeft" )
2931 pValue->Value >>= nTmp;
2932 aRect.setX( nTmp );
2934 else if (pValue->Name == "ViewAreaWidth" )
2936 pValue->Value >>= nTmp;
2937 Size aSize( aRect.GetSize() );
2938 aSize.Width() = nTmp;
2939 aRect.SetSize( aSize );
2941 else if (pValue->Name == "ViewAreaHeight" )
2943 pValue->Value >>= nTmp;
2944 Size aSize( aRect.GetSize() );
2945 aSize.Height() = nTmp;
2946 aRect.SetSize( aSize );
2948 pValue++;
2951 pDocShell->SetVisArea ( aRect );
2954 void SmXMLImport::SetConfigurationSettings(const Sequence<PropertyValue>& aConfProps)
2956 uno::Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
2957 if ( xProps.is() )
2959 Reference < XPropertySetInfo > xInfo ( xProps->getPropertySetInfo() );
2960 if (xInfo.is() )
2962 sal_Int32 nCount = aConfProps.getLength();
2963 const PropertyValue* pValues = aConfProps.getConstArray();
2965 const OUString sFormula ( "Formula" );
2966 const OUString sBasicLibraries ( "BasicLibraries" );
2967 const OUString sDialogLibraries ( "DialogLibraries" );
2968 while ( nCount-- )
2970 if (pValues->Name != sFormula &&
2971 pValues->Name != sBasicLibraries &&
2972 pValues->Name != sDialogLibraries)
2976 if ( xInfo->hasPropertyByName( pValues->Name ) )
2977 xProps->setPropertyValue( pValues->Name, pValues->Value );
2979 catch (const beans::PropertyVetoException &)
2981 // dealing with read-only properties here. Nothing to do...
2983 catch( Exception& rEx)
2985 SAL_WARN("starmath", "SmXMLImport::SetConfigurationSettings: Exception: " << rEx.Message );
2989 pValues++;
2999 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */