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