xref: /trunk/main/starmath/source/mathmlexport.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_starmath.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir /*
32*cdf0e10cSrcweir  Warning: The SvXMLElementExport helper class creates the beginning and
33*cdf0e10cSrcweir  closing tags of xml elements in its constructor and destructor, so theres
34*cdf0e10cSrcweir  hidden stuff going on, on occasion the ordering of these classes declarations
35*cdf0e10cSrcweir  may be significant
36*cdf0e10cSrcweir */
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XErrorHandler.hpp>
40*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XEntityResolver.hpp>
41*cdf0e10cSrcweir #include <com/sun/star/xml/sax/InputSource.hpp>
42*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XDTDHandler.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/xml/sax/XParser.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataControl.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/document/XDocumentProperties.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/packages/zip/ZipIOException.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/uno/Any.h>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #include <rtl/math.hxx>
56*cdf0e10cSrcweir #include <sfx2/frame.hxx>
57*cdf0e10cSrcweir #include <sfx2/docfile.hxx>
58*cdf0e10cSrcweir #include <tools/debug.hxx>
59*cdf0e10cSrcweir #include <tools/urlobj.hxx>
60*cdf0e10cSrcweir #include <svtools/sfxecode.hxx>
61*cdf0e10cSrcweir #include <unotools/saveopt.hxx>
62*cdf0e10cSrcweir #include <svl/stritem.hxx>
63*cdf0e10cSrcweir #include <svl/itemprop.hxx>
64*cdf0e10cSrcweir #include <unotools/processfactory.hxx>
65*cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
66*cdf0e10cSrcweir #include <xmloff/xmlnmspe.hxx>
67*cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
68*cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
69*cdf0e10cSrcweir #include <xmloff/attrlist.hxx>
70*cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
71*cdf0e10cSrcweir #include <xmloff/xmlmetai.hxx>
72*cdf0e10cSrcweir #include <osl/mutex.hxx>
73*cdf0e10cSrcweir #include <comphelper/genericpropertyset.hxx>
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir #include <memory>
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir #include "mathmlexport.hxx"
78*cdf0e10cSrcweir #include <starmath.hrc>
79*cdf0e10cSrcweir #include <unomodel.hxx>
80*cdf0e10cSrcweir #include <document.hxx>
81*cdf0e10cSrcweir #include <utility.hxx>
82*cdf0e10cSrcweir #include <config.hxx>
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir using namespace ::com::sun::star::beans;
85*cdf0e10cSrcweir using namespace ::com::sun::star::container;
86*cdf0e10cSrcweir using namespace ::com::sun::star::document;
87*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
88*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
89*cdf0e10cSrcweir using namespace ::com::sun::star;
90*cdf0e10cSrcweir using namespace ::xmloff::token;
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir using ::rtl::OUString;
93*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir #define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir #undef WANTEXCEPT
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::Export(SfxMedium &rMedium)
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir     sal_Bool bRet=sal_True;
105*cdf0e10cSrcweir     uno::Reference<lang::XMultiServiceFactory>
106*cdf0e10cSrcweir         xServiceFactory(utl::getProcessServiceFactory());
107*cdf0e10cSrcweir     DBG_ASSERT(xServiceFactory.is(),"got no service manager");
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir     //Get model
110*cdf0e10cSrcweir     uno::Reference< lang::XComponent > xModelComp(xModel, uno::UNO_QUERY );
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir     sal_Bool bEmbedded = sal_False;
113*cdf0e10cSrcweir     uno::Reference <lang::XUnoTunnel> xTunnel;
114*cdf0e10cSrcweir     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
115*cdf0e10cSrcweir     SmModel *pModel = reinterpret_cast<SmModel *>
116*cdf0e10cSrcweir         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir     SmDocShell *pDocShell = pModel ?
119*cdf0e10cSrcweir             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
120*cdf0e10cSrcweir     if ( pDocShell &&
121*cdf0e10cSrcweir         SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
122*cdf0e10cSrcweir         bEmbedded = sal_True;
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir     uno::Reference<task::XStatusIndicator> xStatusIndicator;
125*cdf0e10cSrcweir     if (!bEmbedded)
126*cdf0e10cSrcweir     {
127*cdf0e10cSrcweir         if (pDocShell /*&& pDocShell->GetMedium()*/)
128*cdf0e10cSrcweir         {
129*cdf0e10cSrcweir             DBG_ASSERT( pDocShell->GetMedium() == &rMedium,
130*cdf0e10cSrcweir                     "different SfxMedium found" );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir             SfxItemSet* pSet = rMedium.GetItemSet();
133*cdf0e10cSrcweir             if (pSet)
134*cdf0e10cSrcweir             {
135*cdf0e10cSrcweir                 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
136*cdf0e10cSrcweir                     pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
137*cdf0e10cSrcweir                 if (pItem)
138*cdf0e10cSrcweir                     pItem->GetValue() >>= xStatusIndicator;
139*cdf0e10cSrcweir             }
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir         // set progress range and start status indicator
143*cdf0e10cSrcweir         if (xStatusIndicator.is())
144*cdf0e10cSrcweir         {
145*cdf0e10cSrcweir             sal_Int32 nProgressRange = bFlat ? 1 : 3;
146*cdf0e10cSrcweir             xStatusIndicator->start(String(SmResId(STR_STATSTR_WRITING)),
147*cdf0e10cSrcweir                 nProgressRange);
148*cdf0e10cSrcweir         }
149*cdf0e10cSrcweir     }
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir     // create XPropertySet with three properties for status indicator
153*cdf0e10cSrcweir     comphelper::PropertyMapEntry aInfoMap[] =
154*cdf0e10cSrcweir     {
155*cdf0e10cSrcweir         { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
156*cdf0e10cSrcweir               &::getBooleanCppuType(),
157*cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0},
158*cdf0e10cSrcweir         { "BaseURI", sizeof("BaseURI")-1, 0,
159*cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
160*cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
161*cdf0e10cSrcweir         { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
162*cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
163*cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
164*cdf0e10cSrcweir         { "StreamName", sizeof("StreamName")-1, 0,
165*cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
166*cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
167*cdf0e10cSrcweir         { NULL, 0, 0, NULL, 0, 0 }
168*cdf0e10cSrcweir     };
169*cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xInfoSet(
170*cdf0e10cSrcweir                 comphelper::GenericPropertySet_CreateInstance(
171*cdf0e10cSrcweir                             new comphelper::PropertySetInfo( aInfoMap ) ) );
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir     SvtSaveOptions aSaveOpt;
174*cdf0e10cSrcweir     OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
175*cdf0e10cSrcweir     sal_Bool bUsePrettyPrinting( bFlat || aSaveOpt.IsPrettyPrinting() );
176*cdf0e10cSrcweir     Any aAny;
177*cdf0e10cSrcweir     aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
178*cdf0e10cSrcweir     xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir     // Set base URI
181*cdf0e10cSrcweir     OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
182*cdf0e10cSrcweir     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL( true ) ) );
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir     sal_Int32 nSteps=0;
185*cdf0e10cSrcweir     if (xStatusIndicator.is())
186*cdf0e10cSrcweir             xStatusIndicator->setValue(nSteps++);
187*cdf0e10cSrcweir     if (!bFlat) //Storage (Package) of Stream
188*cdf0e10cSrcweir     {
189*cdf0e10cSrcweir         uno::Reference < embed::XStorage > xStg = rMedium.GetOutputStorage();
190*cdf0e10cSrcweir         sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir         // TODO/LATER: handle the case of embedded links gracefully
193*cdf0e10cSrcweir         if ( bEmbedded ) //&& !pStg->IsRoot() )
194*cdf0e10cSrcweir         {
195*cdf0e10cSrcweir             OUString aName;
196*cdf0e10cSrcweir             if ( rMedium.GetItemSet() )
197*cdf0e10cSrcweir             {
198*cdf0e10cSrcweir                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
199*cdf0e10cSrcweir                     rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
200*cdf0e10cSrcweir                 if ( pDocHierarchItem )
201*cdf0e10cSrcweir                     aName = pDocHierarchItem->GetValue();
202*cdf0e10cSrcweir             }
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir             if ( aName.getLength() )
205*cdf0e10cSrcweir             {
206*cdf0e10cSrcweir                 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
207*cdf0e10cSrcweir                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
208*cdf0e10cSrcweir             }
209*cdf0e10cSrcweir         }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir         if ( !bEmbedded )
212*cdf0e10cSrcweir         {
213*cdf0e10cSrcweir             if (xStatusIndicator.is())
214*cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir             bRet = WriteThroughComponent(
217*cdf0e10cSrcweir                     xStg, xModelComp, "meta.xml", xServiceFactory, xInfoSet,
218*cdf0e10cSrcweir                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaExporter"
219*cdf0e10cSrcweir                             : "com.sun.star.comp.Math.XMLMetaExporter"),
220*cdf0e10cSrcweir                     sal_False);
221*cdf0e10cSrcweir         }
222*cdf0e10cSrcweir         if ( bRet )
223*cdf0e10cSrcweir         {
224*cdf0e10cSrcweir            if (xStatusIndicator.is())
225*cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir             bRet = WriteThroughComponent(
228*cdf0e10cSrcweir                     xStg, xModelComp, "content.xml", xServiceFactory, xInfoSet,
229*cdf0e10cSrcweir                     "com.sun.star.comp.Math.XMLContentExporter");
230*cdf0e10cSrcweir         }
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir         if ( bRet )
233*cdf0e10cSrcweir         {
234*cdf0e10cSrcweir             if (xStatusIndicator.is())
235*cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir             bRet = WriteThroughComponent(
238*cdf0e10cSrcweir                     xStg, xModelComp, "settings.xml", xServiceFactory, xInfoSet,
239*cdf0e10cSrcweir                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
240*cdf0e10cSrcweir                             : "com.sun.star.comp.Math.XMLSettingsExporter") );
241*cdf0e10cSrcweir         }
242*cdf0e10cSrcweir     }
243*cdf0e10cSrcweir     else
244*cdf0e10cSrcweir     {
245*cdf0e10cSrcweir         SvStream *pStream = rMedium.GetOutStream();
246*cdf0e10cSrcweir         uno::Reference<io::XOutputStream> xOut(
247*cdf0e10cSrcweir             new utl::OOutputStreamWrapper(*pStream) );
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir         if (xStatusIndicator.is())
250*cdf0e10cSrcweir             xStatusIndicator->setValue(nSteps++);
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir         bRet = WriteThroughComponent(
253*cdf0e10cSrcweir             xOut, xModelComp, xServiceFactory, xInfoSet,
254*cdf0e10cSrcweir             "com.sun.star.comp.Math.XMLContentExporter");
255*cdf0e10cSrcweir     }
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir     if (xStatusIndicator.is())
258*cdf0e10cSrcweir         xStatusIndicator->end();
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir     return bRet;
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir /// export through an XML exporter component (output stream version)
265*cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::WriteThroughComponent(
266*cdf0e10cSrcweir     Reference<io::XOutputStream> xOutputStream,
267*cdf0e10cSrcweir     Reference<XComponent> xComponent,
268*cdf0e10cSrcweir     Reference<lang::XMultiServiceFactory> & rFactory,
269*cdf0e10cSrcweir     Reference<beans::XPropertySet> & rPropSet,
270*cdf0e10cSrcweir     const sal_Char* pComponentName )
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir     DBG_ASSERT(xOutputStream.is(), "I really need an output stream!");
273*cdf0e10cSrcweir     DBG_ASSERT(xComponent.is(), "Need component!");
274*cdf0e10cSrcweir     DBG_ASSERT(NULL != pComponentName, "Need component name!");
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir     // get component
277*cdf0e10cSrcweir     Reference< io::XActiveDataSource > xSaxWriter(
278*cdf0e10cSrcweir         rFactory->createInstance(
279*cdf0e10cSrcweir             OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
280*cdf0e10cSrcweir         UNO_QUERY );
281*cdf0e10cSrcweir     DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
282*cdf0e10cSrcweir     if (!xSaxWriter.is())
283*cdf0e10cSrcweir         return sal_False;
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir     // connect XML writer to output stream
286*cdf0e10cSrcweir     xSaxWriter->setOutputStream( xOutputStream );
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     // prepare arguments (prepend doc handler to given arguments)
289*cdf0e10cSrcweir     Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir     Sequence<Any> aArgs( 2 );
292*cdf0e10cSrcweir     aArgs[0] <<= xDocHandler;
293*cdf0e10cSrcweir     aArgs[1] <<= rPropSet;
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir     // get filter component
296*cdf0e10cSrcweir     Reference< document::XExporter > xExporter(
297*cdf0e10cSrcweir         rFactory->createInstanceWithArguments(
298*cdf0e10cSrcweir             OUString::createFromAscii(pComponentName), aArgs), UNO_QUERY);
299*cdf0e10cSrcweir     DBG_ASSERT( xExporter.is(),
300*cdf0e10cSrcweir             "can't instantiate export filter component" );
301*cdf0e10cSrcweir     if ( !xExporter.is() )
302*cdf0e10cSrcweir         return sal_False;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir     // connect model and filter
306*cdf0e10cSrcweir     xExporter->setSourceDocument( xComponent );
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir     // filter!
309*cdf0e10cSrcweir     Reference < XFilter > xFilter( xExporter, UNO_QUERY );
310*cdf0e10cSrcweir     uno::Sequence< PropertyValue > aProps(0);
311*cdf0e10cSrcweir     xFilter->filter( aProps );
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir     uno::Reference<lang::XUnoTunnel> xFilterTunnel;
314*cdf0e10cSrcweir     xFilterTunnel = uno::Reference<lang::XUnoTunnel>
315*cdf0e10cSrcweir         ( xFilter, uno::UNO_QUERY );
316*cdf0e10cSrcweir     SmXMLExport *pFilter = reinterpret_cast< SmXMLExport * >(
317*cdf0e10cSrcweir                 sal::static_int_cast< sal_uIntPtr >(
318*cdf0e10cSrcweir                 xFilterTunnel->getSomething( SmXMLExport::getUnoTunnelId() )));
319*cdf0e10cSrcweir     return pFilter ? pFilter->GetSuccess() : sal_True;
320*cdf0e10cSrcweir }
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir 
323*cdf0e10cSrcweir /// export through an XML exporter component (storage version)
324*cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::WriteThroughComponent(
325*cdf0e10cSrcweir     const Reference < embed::XStorage >& xStorage,
326*cdf0e10cSrcweir     Reference<XComponent> xComponent,
327*cdf0e10cSrcweir     const sal_Char* pStreamName,
328*cdf0e10cSrcweir     Reference<lang::XMultiServiceFactory> & rFactory,
329*cdf0e10cSrcweir     Reference<beans::XPropertySet> & rPropSet,
330*cdf0e10cSrcweir     const sal_Char* pComponentName,
331*cdf0e10cSrcweir     sal_Bool bCompress
332*cdf0e10cSrcweir     )
333*cdf0e10cSrcweir {
334*cdf0e10cSrcweir     DBG_ASSERT(xStorage.is(), "Need storage!");
335*cdf0e10cSrcweir     DBG_ASSERT(NULL != pStreamName, "Need stream name!");
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir     // open stream
338*cdf0e10cSrcweir     Reference < io::XStream > xStream;
339*cdf0e10cSrcweir     OUString sStreamName = OUString::createFromAscii(pStreamName);
340*cdf0e10cSrcweir     try
341*cdf0e10cSrcweir     {
342*cdf0e10cSrcweir         xStream = xStorage->openStreamElement( sStreamName,
343*cdf0e10cSrcweir             embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
344*cdf0e10cSrcweir     }
345*cdf0e10cSrcweir     catch ( uno::Exception& )
346*cdf0e10cSrcweir     {
347*cdf0e10cSrcweir         DBG_ERROR( "Can't create output stream in package!" );
348*cdf0e10cSrcweir         return sal_False;
349*cdf0e10cSrcweir     }
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
352*cdf0e10cSrcweir     OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
353*cdf0e10cSrcweir     uno::Any aAny;
354*cdf0e10cSrcweir     aAny <<= aMime;
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir     uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
357*cdf0e10cSrcweir     xSet->setPropertyValue( aPropName, aAny );
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir     if ( !bCompress )
360*cdf0e10cSrcweir     {
361*cdf0e10cSrcweir         aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
362*cdf0e10cSrcweir         sal_Bool bFalse = sal_False;
363*cdf0e10cSrcweir         aAny.setValue( &bFalse, ::getBooleanCppuType() );
364*cdf0e10cSrcweir         xSet->setPropertyValue( aPropName, aAny );
365*cdf0e10cSrcweir     }
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir     // even plain stream must be encrypted in encrypted document
368*cdf0e10cSrcweir     OUString aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
369*cdf0e10cSrcweir     sal_Bool bTrue = sal_True;
370*cdf0e10cSrcweir     aAny.setValue( &bTrue, ::getBooleanCppuType() );
371*cdf0e10cSrcweir     xSet->setPropertyValue( aTmpPropName, aAny );
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir     // set Base URL
374*cdf0e10cSrcweir     if ( rPropSet.is() )
375*cdf0e10cSrcweir     {
376*cdf0e10cSrcweir         OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
377*cdf0e10cSrcweir         rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
378*cdf0e10cSrcweir     }
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir     // write the stuff
381*cdf0e10cSrcweir     sal_Bool bRet = WriteThroughComponent( xStream->getOutputStream(), xComponent, rFactory,
382*cdf0e10cSrcweir         rPropSet, pComponentName );
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir     // stream is closed by SAX parser
385*cdf0e10cSrcweir     //if ( bRet )
386*cdf0e10cSrcweir     //    xStream->getOutputStream()->closeOutput();
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir     return bRet;
389*cdf0e10cSrcweir }
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir // #110680#
394*cdf0e10cSrcweir SmXMLExport::SmXMLExport(
395*cdf0e10cSrcweir     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
396*cdf0e10cSrcweir     sal_uInt16 nExportFlags)
397*cdf0e10cSrcweir :   SvXMLExport( xServiceFactory, MAP_INCH, XML_MATH, nExportFlags ) ,
398*cdf0e10cSrcweir     pTree(0) ,
399*cdf0e10cSrcweir     bSuccess(sal_False)
400*cdf0e10cSrcweir {
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir sal_Int64 SAL_CALL SmXMLExport::getSomething(
404*cdf0e10cSrcweir     const uno::Sequence< sal_Int8 >& rId )
405*cdf0e10cSrcweir throw(uno::RuntimeException)
406*cdf0e10cSrcweir {
407*cdf0e10cSrcweir     if ( rId.getLength() == 16 &&
408*cdf0e10cSrcweir         0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
409*cdf0e10cSrcweir         rId.getConstArray(), 16 ) )
410*cdf0e10cSrcweir     return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     return SvXMLExport::getSomething( rId );
413*cdf0e10cSrcweir }
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir const uno::Sequence< sal_Int8 > & SmXMLExport::getUnoTunnelId() throw()
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir     static uno::Sequence< sal_Int8 > * pSeq = 0;
418*cdf0e10cSrcweir     if ( !pSeq )
419*cdf0e10cSrcweir     {
420*cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
421*cdf0e10cSrcweir         if ( !pSeq )
422*cdf0e10cSrcweir         {
423*cdf0e10cSrcweir             static uno::Sequence< sal_Int8 > aSeq( 16 );
424*cdf0e10cSrcweir             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
425*cdf0e10cSrcweir             pSeq = &aSeq;
426*cdf0e10cSrcweir         }
427*cdf0e10cSrcweir     }
428*cdf0e10cSrcweir     return *pSeq;
429*cdf0e10cSrcweir }
430*cdf0e10cSrcweir 
431*cdf0e10cSrcweir OUString SAL_CALL SmXMLExport_getImplementationName() throw()
432*cdf0e10cSrcweir {
433*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
434*cdf0e10cSrcweir }
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExport_getSupportedServiceNames()
437*cdf0e10cSrcweir         throw()
438*cdf0e10cSrcweir {
439*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
440*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
441*cdf0e10cSrcweir     return aSeq;
442*cdf0e10cSrcweir }
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExport_createInstance(
445*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
446*cdf0e10cSrcweir     throw( uno::Exception )
447*cdf0e10cSrcweir {
448*cdf0e10cSrcweir     // #110680#
449*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
450*cdf0e10cSrcweir     // EXPORT_OASIS is required here allthough there is no differrence between
451*cdf0e10cSrcweir     // OOo and OASIS, because without the flag, a transformation to OOo would
452*cdf0e10cSrcweir     // be chained in.
453*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_ALL );
454*cdf0e10cSrcweir }
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName() throw()
459*cdf0e10cSrcweir {
460*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
461*cdf0e10cSrcweir }
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames()
464*cdf0e10cSrcweir     throw()
465*cdf0e10cSrcweir {
466*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
467*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
468*cdf0e10cSrcweir     return aSeq;
469*cdf0e10cSrcweir }
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance(
472*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
473*cdf0e10cSrcweir throw( uno::Exception )
474*cdf0e10cSrcweir {
475*cdf0e10cSrcweir     // #110680#
476*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
477*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_META );
478*cdf0e10cSrcweir }
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir OUString SAL_CALL SmXMLExportMeta_getImplementationName() throw()
483*cdf0e10cSrcweir {
484*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
485*cdf0e10cSrcweir }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames()
488*cdf0e10cSrcweir throw()
489*cdf0e10cSrcweir {
490*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
491*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
492*cdf0e10cSrcweir     return aSeq;
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMeta_createInstance(
496*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
497*cdf0e10cSrcweir throw( uno::Exception )
498*cdf0e10cSrcweir {
499*cdf0e10cSrcweir     // #110680#
500*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
501*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_META );
502*cdf0e10cSrcweir }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName() throw()
507*cdf0e10cSrcweir {
508*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
509*cdf0e10cSrcweir }
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames()
512*cdf0e10cSrcweir throw()
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
515*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
516*cdf0e10cSrcweir     return aSeq;
517*cdf0e10cSrcweir }
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance(
520*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
521*cdf0e10cSrcweir throw( uno::Exception )
522*cdf0e10cSrcweir {
523*cdf0e10cSrcweir     // #110680#
524*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
525*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_SETTINGS );
526*cdf0e10cSrcweir }
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir OUString SAL_CALL SmXMLExportSettings_getImplementationName() throw()
531*cdf0e10cSrcweir {
532*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
533*cdf0e10cSrcweir }
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames()
536*cdf0e10cSrcweir throw()
537*cdf0e10cSrcweir {
538*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
539*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
540*cdf0e10cSrcweir     return aSeq;
541*cdf0e10cSrcweir }
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettings_createInstance(
544*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
545*cdf0e10cSrcweir throw( uno::Exception )
546*cdf0e10cSrcweir {
547*cdf0e10cSrcweir     // #110680#
548*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
549*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_SETTINGS );
550*cdf0e10cSrcweir }
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir OUString SAL_CALL SmXMLExportContent_getImplementationName() throw()
555*cdf0e10cSrcweir {
556*cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
557*cdf0e10cSrcweir }
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames()
560*cdf0e10cSrcweir         throw()
561*cdf0e10cSrcweir {
562*cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
563*cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
564*cdf0e10cSrcweir     return aSeq;
565*cdf0e10cSrcweir }
566*cdf0e10cSrcweir 
567*cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportContent_createInstance(
568*cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
569*cdf0e10cSrcweir throw( uno::Exception )
570*cdf0e10cSrcweir {
571*cdf0e10cSrcweir     // #110680#
572*cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
573*cdf0e10cSrcweir     // The EXPORT_OASIS flag is only required to avoid that a transformer is
574*cdf0e10cSrcweir     // chanied in
575*cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_CONTENT );
576*cdf0e10cSrcweir }
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
579*cdf0e10cSrcweir 
580*cdf0e10cSrcweir // XServiceInfo
581*cdf0e10cSrcweir // override empty method from parent class
582*cdf0e10cSrcweir rtl::OUString SAL_CALL SmXMLExport::getImplementationName()
583*cdf0e10cSrcweir throw(uno::RuntimeException)
584*cdf0e10cSrcweir {
585*cdf0e10cSrcweir     OUString aTxt;
586*cdf0e10cSrcweir     switch( getExportFlags() )
587*cdf0e10cSrcweir     {
588*cdf0e10cSrcweir         case EXPORT_META:
589*cdf0e10cSrcweir             aTxt = SmXMLExportMeta_getImplementationName();
590*cdf0e10cSrcweir             break;
591*cdf0e10cSrcweir         case EXPORT_SETTINGS:
592*cdf0e10cSrcweir             aTxt = SmXMLExportSettings_getImplementationName();
593*cdf0e10cSrcweir             break;
594*cdf0e10cSrcweir         case EXPORT_CONTENT:
595*cdf0e10cSrcweir             aTxt = SmXMLExportContent_getImplementationName();
596*cdf0e10cSrcweir             break;
597*cdf0e10cSrcweir         case EXPORT_ALL:
598*cdf0e10cSrcweir         default:
599*cdf0e10cSrcweir             aTxt = SmXMLExport_getImplementationName();
600*cdf0e10cSrcweir             break;
601*cdf0e10cSrcweir     }
602*cdf0e10cSrcweir     return aTxt;
603*cdf0e10cSrcweir }
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir sal_uInt32 SmXMLExport::exportDoc(enum XMLTokenEnum eClass)
606*cdf0e10cSrcweir {
607*cdf0e10cSrcweir     if ( (getExportFlags() & EXPORT_CONTENT) == 0 )
608*cdf0e10cSrcweir     {
609*cdf0e10cSrcweir         SvXMLExport::exportDoc( eClass );
610*cdf0e10cSrcweir     }
611*cdf0e10cSrcweir     else
612*cdf0e10cSrcweir     {
613*cdf0e10cSrcweir         uno::Reference <frame::XModel> xModel = GetModel();
614*cdf0e10cSrcweir         uno::Reference <lang::XUnoTunnel> xTunnel;
615*cdf0e10cSrcweir         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
616*cdf0e10cSrcweir         SmModel *pModel = reinterpret_cast<SmModel *>
617*cdf0e10cSrcweir             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir         if (pModel)
620*cdf0e10cSrcweir         {
621*cdf0e10cSrcweir             SmDocShell *pDocShell =
622*cdf0e10cSrcweir                 static_cast<SmDocShell*>(pModel->GetObjectShell());
623*cdf0e10cSrcweir             pTree = pDocShell->GetFormulaTree();
624*cdf0e10cSrcweir             aText = pDocShell->GetText();
625*cdf0e10cSrcweir         }
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir         GetDocHandler()->startDocument();
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir         /*Add xmlns line*/
630*cdf0e10cSrcweir         SvXMLAttributeList &rList = GetAttrList();
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir         // make use of a default namespace
633*cdf0e10cSrcweir         ResetNamespaceMap();    // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
634*cdf0e10cSrcweir         _GetNamespaceMap().Add( OUString::createFromAscii(""), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir         rList.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX),
637*cdf0e10cSrcweir                 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX));
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir         //I think we need something like ImplExportEntities();
640*cdf0e10cSrcweir         _ExportContent();
641*cdf0e10cSrcweir         GetDocHandler()->endDocument();
642*cdf0e10cSrcweir     }
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir     bSuccess=sal_True;
645*cdf0e10cSrcweir     return 0;
646*cdf0e10cSrcweir }
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir void SmXMLExport::_ExportContent()
649*cdf0e10cSrcweir {
650*cdf0e10cSrcweir     SvXMLElementExport aEquation(*this, XML_NAMESPACE_MATH, XML_MATH, sal_True, sal_True);
651*cdf0e10cSrcweir     SvXMLElementExport *pSemantics=0;
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir     if (aText.Len())
654*cdf0e10cSrcweir     {
655*cdf0e10cSrcweir         pSemantics = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
656*cdf0e10cSrcweir             XML_SEMANTICS, sal_True, sal_True);
657*cdf0e10cSrcweir     }
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir     ExportNodes(pTree, 0);
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir     if (aText.Len())
662*cdf0e10cSrcweir     {
663*cdf0e10cSrcweir         // Convert symbol names
664*cdf0e10cSrcweir         uno::Reference <frame::XModel> xModel = GetModel();
665*cdf0e10cSrcweir         uno::Reference <lang::XUnoTunnel> xTunnel;
666*cdf0e10cSrcweir         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
667*cdf0e10cSrcweir         SmModel *pModel = reinterpret_cast<SmModel *>
668*cdf0e10cSrcweir             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
669*cdf0e10cSrcweir         SmDocShell *pDocShell = pModel ?
670*cdf0e10cSrcweir             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
671*cdf0e10cSrcweir         DBG_ASSERT( pDocShell, "doc shell missing" );
672*cdf0e10cSrcweir         if (pDocShell)
673*cdf0e10cSrcweir         {
674*cdf0e10cSrcweir             SmParser &rParser = pDocShell->GetParser();
675*cdf0e10cSrcweir             sal_Bool bVal = rParser.IsExportSymbolNames();
676*cdf0e10cSrcweir             rParser.SetExportSymbolNames( sal_True );
677*cdf0e10cSrcweir             SmNode *pTmpTree = rParser.Parse( aText );
678*cdf0e10cSrcweir             aText = rParser.GetText();
679*cdf0e10cSrcweir             delete pTmpTree;
680*cdf0e10cSrcweir             rParser.SetExportSymbolNames( bVal );
681*cdf0e10cSrcweir         }
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ENCODING,
684*cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
685*cdf0e10cSrcweir         SvXMLElementExport aAnnotation(*this, XML_NAMESPACE_MATH,
686*cdf0e10cSrcweir             XML_ANNOTATION, sal_True, sal_False);
687*cdf0e10cSrcweir         GetDocHandler()->characters(OUString( aText ));
688*cdf0e10cSrcweir     }
689*cdf0e10cSrcweir     delete pSemantics;
690*cdf0e10cSrcweir }
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir void SmXMLExport::GetViewSettings( Sequence < PropertyValue >& aProps)
693*cdf0e10cSrcweir {
694*cdf0e10cSrcweir     uno::Reference <frame::XModel> xModel = GetModel();
695*cdf0e10cSrcweir     if ( !xModel.is() )
696*cdf0e10cSrcweir         return;
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir     uno::Reference <lang::XUnoTunnel> xTunnel;
699*cdf0e10cSrcweir     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
700*cdf0e10cSrcweir     SmModel *pModel = reinterpret_cast<SmModel *>
701*cdf0e10cSrcweir         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir     if ( !pModel )
704*cdf0e10cSrcweir         return;
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir     SmDocShell *pDocShell =
707*cdf0e10cSrcweir         static_cast<SmDocShell*>(pModel->GetObjectShell());
708*cdf0e10cSrcweir     if ( !pDocShell )
709*cdf0e10cSrcweir         return;
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir     aProps.realloc( 4 );
712*cdf0e10cSrcweir     PropertyValue *pValue = aProps.getArray();
713*cdf0e10cSrcweir     sal_Int32 nIndex = 0;
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir     Rectangle aRect( pDocShell->GetVisArea() );
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
718*cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.Top();
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
721*cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.Left();
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
724*cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.GetWidth();
725*cdf0e10cSrcweir 
726*cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
727*cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.GetHeight();
728*cdf0e10cSrcweir }
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir void SmXMLExport::GetConfigurationSettings( Sequence < PropertyValue > & rProps)
731*cdf0e10cSrcweir {
732*cdf0e10cSrcweir     Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
733*cdf0e10cSrcweir     if ( xProps.is() )
734*cdf0e10cSrcweir     {
735*cdf0e10cSrcweir         Reference< XPropertySetInfo > xPropertySetInfo = xProps->getPropertySetInfo();
736*cdf0e10cSrcweir         if (xPropertySetInfo.is())
737*cdf0e10cSrcweir         {
738*cdf0e10cSrcweir             Sequence< Property > aProps = xPropertySetInfo->getProperties();
739*cdf0e10cSrcweir             sal_Int32 nCount(aProps.getLength());
740*cdf0e10cSrcweir             if (nCount > 0)
741*cdf0e10cSrcweir             {
742*cdf0e10cSrcweir                 rProps.realloc(nCount);
743*cdf0e10cSrcweir                 PropertyValue* pProps = rProps.getArray();
744*cdf0e10cSrcweir                 if (pProps)
745*cdf0e10cSrcweir                 {
746*cdf0e10cSrcweir                     SmConfig *pConfig = SM_MOD()->GetConfig();
747*cdf0e10cSrcweir                     const bool bUsedSymbolsOnly = pConfig ? pConfig->IsSaveOnlyUsedSymbols() : false;
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir                     const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
750*cdf0e10cSrcweir                     const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
751*cdf0e10cSrcweir                     const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
752*cdf0e10cSrcweir                     const OUString sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
753*cdf0e10cSrcweir                     for (sal_Int32 i = 0; i < nCount; i++, pProps++)
754*cdf0e10cSrcweir                     {
755*cdf0e10cSrcweir                         const OUString &rPropName = aProps[i].Name;
756*cdf0e10cSrcweir                         if (rPropName != sFormula &&
757*cdf0e10cSrcweir                             rPropName != sBasicLibraries &&
758*cdf0e10cSrcweir                             rPropName != sDialogLibraries &&
759*cdf0e10cSrcweir                             rPropName != sRuntimeUID)
760*cdf0e10cSrcweir                         {
761*cdf0e10cSrcweir                             pProps->Name = rPropName;
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir                             rtl::OUString aActualName( rPropName );
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir                             // handle 'save used symbols only'
766*cdf0e10cSrcweir                             if (bUsedSymbolsOnly && rPropName.equalsAscii("Symbols"))
767*cdf0e10cSrcweir                                 aActualName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "UserDefinedSymbolsInUse" ) );
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir                             pProps->Value = xProps->getPropertyValue( aActualName );
770*cdf0e10cSrcweir                         }
771*cdf0e10cSrcweir                     }
772*cdf0e10cSrcweir                 }
773*cdf0e10cSrcweir             }
774*cdf0e10cSrcweir         }
775*cdf0e10cSrcweir     }
776*cdf0e10cSrcweir }
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir void SmXMLExport::ExportLine(const SmNode *pNode, int nLevel)
779*cdf0e10cSrcweir {
780*cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
781*cdf0e10cSrcweir }
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir void SmXMLExport::ExportBinaryHorizontal(const SmNode *pNode, int nLevel)
784*cdf0e10cSrcweir {
785*cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
786*cdf0e10cSrcweir }
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir void SmXMLExport::ExportUnaryHorizontal(const SmNode *pNode, int nLevel)
789*cdf0e10cSrcweir {
790*cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
791*cdf0e10cSrcweir }
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir void SmXMLExport::ExportExpression(const SmNode *pNode, int nLevel)
794*cdf0e10cSrcweir {
795*cdf0e10cSrcweir     SvXMLElementExport *pRow=0;
796*cdf0e10cSrcweir     sal_uLong  nSize = pNode->GetNumSubNodes();
797*cdf0e10cSrcweir 
798*cdf0e10cSrcweir     // #i115443: nodes of type expression always need to be grouped with mrow statement
799*cdf0e10cSrcweir     if (nSize > 1 || (pNode && pNode->GetType() == NEXPRESSION))
800*cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW, sal_True, sal_True);
801*cdf0e10cSrcweir 
802*cdf0e10cSrcweir     //if (nSize)
803*cdf0e10cSrcweir     //{
804*cdf0e10cSrcweir         for (sal_uInt16 i = 0; i < nSize; i++)
805*cdf0e10cSrcweir             if (const SmNode *pTemp = pNode->GetSubNode(i))
806*cdf0e10cSrcweir                 ExportNodes(pTemp, nLevel+1);
807*cdf0e10cSrcweir     //}
808*cdf0e10cSrcweir #if 0
809*cdf0e10cSrcweir     else
810*cdf0e10cSrcweir     {
811*cdf0e10cSrcweir         //This saves us from situations like "a newline" where the
812*cdf0e10cSrcweir         //lack of a term following the newline would otherwise create
813*cdf0e10cSrcweir         //a incorrect token like <mtr/>
814*cdf0e10cSrcweir         SvXMLElementExport aDummy(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
815*cdf0e10cSrcweir         sal_Unicode nArse[2] = {'\n','\0'};
816*cdf0e10cSrcweir         GetDocHandler()->characters(nArse);
817*cdf0e10cSrcweir     }
818*cdf0e10cSrcweir #endif
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir     delete pRow;
821*cdf0e10cSrcweir }
822*cdf0e10cSrcweir 
823*cdf0e10cSrcweir void SmXMLExport::ExportBinaryVertical(const SmNode *pNode, int nLevel)
824*cdf0e10cSrcweir {
825*cdf0e10cSrcweir     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Fraction");
826*cdf0e10cSrcweir     SvXMLElementExport aFraction(*this, XML_NAMESPACE_MATH, XML_MFRAC, sal_True, sal_True);
827*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(0), nLevel);
828*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(2), nLevel);
829*cdf0e10cSrcweir }
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir void SmXMLExport::ExportTable(const SmNode *pNode, int nLevel)
832*cdf0e10cSrcweir {
833*cdf0e10cSrcweir     SvXMLElementExport *pTable=0;
834*cdf0e10cSrcweir 
835*cdf0e10cSrcweir     sal_uInt16 nSize = pNode->GetNumSubNodes();
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir     //If the list ends in newline then the last entry has
838*cdf0e10cSrcweir     //no subnodes, the newline is superfulous so we just drop
839*cdf0e10cSrcweir     //the last node, inclusion would create a bad MathML
840*cdf0e10cSrcweir     //table
841*cdf0e10cSrcweir     if (nSize >= 1 && pNode->GetSubNode(nSize-1)->GetNumSubNodes() == 0)
842*cdf0e10cSrcweir         --nSize;
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir     // try to avoid creating a mtable element when the formula consists only
845*cdf0e10cSrcweir     // of a single output line
846*cdf0e10cSrcweir     if (nLevel || (nSize >1))
847*cdf0e10cSrcweir         pTable = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
848*cdf0e10cSrcweir 
849*cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < nSize; i++)
850*cdf0e10cSrcweir         if (const SmNode *pTemp = pNode->GetSubNode(i))
851*cdf0e10cSrcweir         {
852*cdf0e10cSrcweir             SvXMLElementExport *pRow=0;
853*cdf0e10cSrcweir             SvXMLElementExport *pCell=0;
854*cdf0e10cSrcweir             if (pTable)
855*cdf0e10cSrcweir             {
856*cdf0e10cSrcweir                 pRow  = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
857*cdf0e10cSrcweir                 pCell = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
858*cdf0e10cSrcweir             }
859*cdf0e10cSrcweir             ExportNodes(pTemp, nLevel+1);
860*cdf0e10cSrcweir             delete pCell;
861*cdf0e10cSrcweir             delete pRow;
862*cdf0e10cSrcweir         }
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir     delete pTable;
865*cdf0e10cSrcweir }
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir void SmXMLExport::ExportMath(const SmNode *pNode, int /*nLevel*/)
868*cdf0e10cSrcweir {
869*cdf0e10cSrcweir     const SmMathSymbolNode *pTemp = static_cast<const SmMathSymbolNode *>(pNode);
870*cdf0e10cSrcweir     SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO, sal_True, sal_False);
871*cdf0e10cSrcweir     sal_Unicode nArse[2];
872*cdf0e10cSrcweir     nArse[0] = pTemp->GetText().GetChar(0);
873*cdf0e10cSrcweir     sal_Unicode cTmp = ConvertMathToMathML( nArse[0] );
874*cdf0e10cSrcweir     if (cTmp != 0)
875*cdf0e10cSrcweir         nArse[0] = cTmp;
876*cdf0e10cSrcweir     DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
877*cdf0e10cSrcweir     nArse[1] = 0;
878*cdf0e10cSrcweir     GetDocHandler()->characters(nArse);
879*cdf0e10cSrcweir }
880*cdf0e10cSrcweir 
881*cdf0e10cSrcweir void SmXMLExport::ExportText(const SmNode *pNode, int /*nLevel*/)
882*cdf0e10cSrcweir {
883*cdf0e10cSrcweir     SvXMLElementExport *pText;
884*cdf0e10cSrcweir     const SmTextNode *pTemp = static_cast<const SmTextNode *>(pNode);
885*cdf0e10cSrcweir     switch (pNode->GetToken().eType)
886*cdf0e10cSrcweir     {
887*cdf0e10cSrcweir         default:
888*cdf0e10cSrcweir         case TIDENT:
889*cdf0e10cSrcweir         {
890*cdf0e10cSrcweir             //Note that we change the fontstyle to italic for strings that
891*cdf0e10cSrcweir             //are italic and longer than a single character.
892*cdf0e10cSrcweir             sal_Bool bIsItalic = IsItalic( pTemp->GetFont() );
893*cdf0e10cSrcweir             if ((pTemp->GetText().Len() > 1) && bIsItalic)
894*cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_ITALIC);
895*cdf0e10cSrcweir             else if ((pTemp->GetText().Len() == 1) && !bIsItalic)
896*cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_NORMAL);
897*cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI,sal_True,sal_False);
898*cdf0e10cSrcweir             break;
899*cdf0e10cSrcweir         }
900*cdf0e10cSrcweir         case TNUMBER:
901*cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MN,sal_True,sal_False);
902*cdf0e10cSrcweir             break;
903*cdf0e10cSrcweir         case TTEXT:
904*cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTEXT,sal_True,sal_False);
905*cdf0e10cSrcweir             break;
906*cdf0e10cSrcweir         }
907*cdf0e10cSrcweir     GetDocHandler()->characters(OUString(pTemp->GetText().GetBuffer()));
908*cdf0e10cSrcweir     delete pText;
909*cdf0e10cSrcweir }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir void SmXMLExport::ExportBlank(const SmNode * /*pNode*/, int /*nLevel*/)
912*cdf0e10cSrcweir {
913*cdf0e10cSrcweir     //!! exports an empty <mi> tag since for example "~_~" is allowed in
914*cdf0e10cSrcweir     //!! Math (so it has no sense at all) but must not result in an empty
915*cdf0e10cSrcweir     //!! <msub> tag in MathML !!
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir     SvXMLElementExport *pText;
918*cdf0e10cSrcweir     //const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir     pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir     GetDocHandler()->characters( OUString() );
923*cdf0e10cSrcweir     delete pText;
924*cdf0e10cSrcweir }
925*cdf0e10cSrcweir 
926*cdf0e10cSrcweir void SmXMLExport::ExportSubSupScript(const SmNode *pNode, int nLevel)
927*cdf0e10cSrcweir {
928*cdf0e10cSrcweir     const SmNode *pSub  = 0;
929*cdf0e10cSrcweir     const SmNode *pSup  = 0;
930*cdf0e10cSrcweir     const SmNode *pCSub = 0;
931*cdf0e10cSrcweir     const SmNode *pCSup = 0;
932*cdf0e10cSrcweir     const SmNode *pLSub = 0;
933*cdf0e10cSrcweir     const SmNode *pLSup = 0;
934*cdf0e10cSrcweir     SvXMLElementExport *pThing = 0, *pThing2 = 0;
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir     //if we have prescripts at all then we must use the tensor notation
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir     //This is one of those excellent locations where scope is vital to
939*cdf0e10cSrcweir     //arrange the construction and destruction of the element helper
940*cdf0e10cSrcweir     //classes correctly
941*cdf0e10cSrcweir     pLSub = pNode->GetSubNode(LSUB+1);
942*cdf0e10cSrcweir     pLSup = pNode->GetSubNode(LSUP+1);
943*cdf0e10cSrcweir     if (pLSub || pLSup)
944*cdf0e10cSrcweir     {
945*cdf0e10cSrcweir         SvXMLElementExport aMultiScripts(*this, XML_NAMESPACE_MATH,
946*cdf0e10cSrcweir             XML_MMULTISCRIPTS, sal_True, sal_True);
947*cdf0e10cSrcweir 
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
950*cdf0e10cSrcweir             && NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
951*cdf0e10cSrcweir         {
952*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
953*cdf0e10cSrcweir                 XML_MUNDEROVER, sal_True,sal_True);
954*cdf0e10cSrcweir         }
955*cdf0e10cSrcweir         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
956*cdf0e10cSrcweir         {
957*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
958*cdf0e10cSrcweir                 XML_MUNDER, sal_True,sal_True);
959*cdf0e10cSrcweir         }
960*cdf0e10cSrcweir         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
961*cdf0e10cSrcweir         {
962*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
963*cdf0e10cSrcweir                 XML_MOVER, sal_True,sal_True);
964*cdf0e10cSrcweir         }
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir         if (pCSub)
969*cdf0e10cSrcweir             ExportNodes(pCSub, nLevel+1);
970*cdf0e10cSrcweir         if (pCSup)
971*cdf0e10cSrcweir             ExportNodes(pCSup, nLevel+1);
972*cdf0e10cSrcweir         delete pThing2;
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir         pSub = pNode->GetSubNode(RSUB+1);
975*cdf0e10cSrcweir         pSup = pNode->GetSubNode(RSUP+1);
976*cdf0e10cSrcweir         if (pSub || pSup)
977*cdf0e10cSrcweir         {
978*cdf0e10cSrcweir             if (pSub)
979*cdf0e10cSrcweir                 ExportNodes(pSub, nLevel+1);
980*cdf0e10cSrcweir             else
981*cdf0e10cSrcweir             {
982*cdf0e10cSrcweir                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
983*cdf0e10cSrcweir             }
984*cdf0e10cSrcweir             if (pSup)
985*cdf0e10cSrcweir                 ExportNodes(pSup, nLevel+1);
986*cdf0e10cSrcweir             else
987*cdf0e10cSrcweir             {
988*cdf0e10cSrcweir                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
989*cdf0e10cSrcweir             }
990*cdf0e10cSrcweir         }
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir         //Seperator element between suffix and prefix sub/sup pairs
993*cdf0e10cSrcweir         {
994*cdf0e10cSrcweir             SvXMLElementExport aPrescripts(*this, XML_NAMESPACE_MATH,
995*cdf0e10cSrcweir                 XML_MPRESCRIPTS, sal_True,sal_True);
996*cdf0e10cSrcweir         }
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir         if (pLSub)
999*cdf0e10cSrcweir             ExportNodes(pLSub, nLevel+1);
1000*cdf0e10cSrcweir         else
1001*cdf0e10cSrcweir         {
1002*cdf0e10cSrcweir             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
1003*cdf0e10cSrcweir                 sal_True,sal_True);
1004*cdf0e10cSrcweir 
1005*cdf0e10cSrcweir         }
1006*cdf0e10cSrcweir         if (pLSup)
1007*cdf0e10cSrcweir             ExportNodes(pLSup, nLevel+1);
1008*cdf0e10cSrcweir         else
1009*cdf0e10cSrcweir         {
1010*cdf0e10cSrcweir             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
1011*cdf0e10cSrcweir                 sal_True,sal_True);
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir         }
1014*cdf0e10cSrcweir     }
1015*cdf0e10cSrcweir     else
1016*cdf0e10cSrcweir     {
1017*cdf0e10cSrcweir         if (NULL != (pSub = pNode->GetSubNode(RSUB+1)) &&
1018*cdf0e10cSrcweir             NULL != (pSup = pNode->GetSubNode(RSUP+1)))
1019*cdf0e10cSrcweir         {
1020*cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1021*cdf0e10cSrcweir                 XML_MSUBSUP, sal_True,sal_True);
1022*cdf0e10cSrcweir         }
1023*cdf0e10cSrcweir         else if (NULL != (pSub = pNode->GetSubNode(RSUB+1)))
1024*cdf0e10cSrcweir         {
1025*cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUB,
1026*cdf0e10cSrcweir                 sal_True,sal_True);
1027*cdf0e10cSrcweir         }
1028*cdf0e10cSrcweir         else if (NULL != (pSup = pNode->GetSubNode(RSUP+1)))
1029*cdf0e10cSrcweir         {
1030*cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUP,
1031*cdf0e10cSrcweir                 sal_True,sal_True);
1032*cdf0e10cSrcweir         }
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
1035*cdf0e10cSrcweir             && NULL != (pCSup=pNode->GetSubNode(CSUP+1)))
1036*cdf0e10cSrcweir         {
1037*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1038*cdf0e10cSrcweir                 XML_MUNDEROVER, sal_True,sal_True);
1039*cdf0e10cSrcweir         }
1040*cdf0e10cSrcweir         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
1041*cdf0e10cSrcweir         {
1042*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1043*cdf0e10cSrcweir                 XML_MUNDER, sal_True,sal_True);
1044*cdf0e10cSrcweir         }
1045*cdf0e10cSrcweir         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
1046*cdf0e10cSrcweir         {
1047*cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1048*cdf0e10cSrcweir                 XML_MOVER, sal_True,sal_True);
1049*cdf0e10cSrcweir         }
1050*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir         if (pCSub)
1053*cdf0e10cSrcweir             ExportNodes(pCSub, nLevel+1);
1054*cdf0e10cSrcweir         if (pCSup)
1055*cdf0e10cSrcweir             ExportNodes(pCSup, nLevel+1);
1056*cdf0e10cSrcweir         delete pThing2;
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir         if (pSub)
1059*cdf0e10cSrcweir             ExportNodes(pSub, nLevel+1);
1060*cdf0e10cSrcweir         if (pSup)
1061*cdf0e10cSrcweir             ExportNodes(pSup, nLevel+1);
1062*cdf0e10cSrcweir         delete pThing;
1063*cdf0e10cSrcweir     }
1064*cdf0e10cSrcweir }
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
1067*cdf0e10cSrcweir {
1068*cdf0e10cSrcweir     const SmNode *pTemp;
1069*cdf0e10cSrcweir     const SmNode *pLeft=pNode->GetSubNode(0);
1070*cdf0e10cSrcweir     const SmNode *pRight=pNode->GetSubNode(2);
1071*cdf0e10cSrcweir     SvXMLElementExport *pFences=0,*pRow=0;
1072*cdf0e10cSrcweir     if ( ((pLeft) && (pLeft->GetToken().eType != TNONE)) &&
1073*cdf0e10cSrcweir         ((pRight) && (pRight->GetToken().eType != TNONE)) &&
1074*cdf0e10cSrcweir         (pNode->GetScaleMode() == SCALE_HEIGHT))
1075*cdf0e10cSrcweir     {
1076*cdf0e10cSrcweir         sal_Unicode nArse[2];
1077*cdf0e10cSrcweir         nArse[1] = 0;
1078*cdf0e10cSrcweir         nArse[0] = static_cast<
1079*cdf0e10cSrcweir             const SmMathSymbolNode* >(pLeft)->GetText().GetChar(0);
1080*cdf0e10cSrcweir         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
1081*cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_OPEN,nArse);
1082*cdf0e10cSrcweir         nArse[0] = static_cast<
1083*cdf0e10cSrcweir             const SmMathSymbolNode* >(pRight)->GetText().GetChar(0);
1084*cdf0e10cSrcweir         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
1085*cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_CLOSE,nArse);
1086*cdf0e10cSrcweir         pFences = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MFENCED,
1087*cdf0e10cSrcweir             sal_True,sal_True);
1088*cdf0e10cSrcweir     }
1089*cdf0e10cSrcweir     else if (pLeft && (pLeft->GetToken().eType != TNONE))
1090*cdf0e10cSrcweir     {
1091*cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
1092*cdf0e10cSrcweir             sal_True, sal_True);
1093*cdf0e10cSrcweir         if (pNode->GetScaleMode() == SCALE_HEIGHT)
1094*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
1095*cdf0e10cSrcweir         else
1096*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1097*cdf0e10cSrcweir         ExportNodes(pLeft, nLevel+1);
1098*cdf0e10cSrcweir     }
1099*cdf0e10cSrcweir     else
1100*cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
1101*cdf0e10cSrcweir             sal_True, sal_True);
1102*cdf0e10cSrcweir 
1103*cdf0e10cSrcweir     if (NULL != (pTemp = pNode->GetSubNode(1)))
1104*cdf0e10cSrcweir         ExportNodes(pTemp, nLevel+1);
1105*cdf0e10cSrcweir     if (pFences)
1106*cdf0e10cSrcweir         delete pFences;
1107*cdf0e10cSrcweir     else if (pRight && (pRight->GetToken().eType != TNONE))
1108*cdf0e10cSrcweir     {
1109*cdf0e10cSrcweir         if (pNode->GetScaleMode() == SCALE_HEIGHT)
1110*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
1111*cdf0e10cSrcweir         else
1112*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1113*cdf0e10cSrcweir         ExportNodes(pRight, nLevel+1);
1114*cdf0e10cSrcweir     }
1115*cdf0e10cSrcweir     delete pRow;
1116*cdf0e10cSrcweir }
1117*cdf0e10cSrcweir 
1118*cdf0e10cSrcweir void SmXMLExport::ExportRoot(const SmNode *pNode, int nLevel)
1119*cdf0e10cSrcweir {
1120*cdf0e10cSrcweir     if (pNode->GetSubNode(0))
1121*cdf0e10cSrcweir     {
1122*cdf0e10cSrcweir         SvXMLElementExport aRoot(*this, XML_NAMESPACE_MATH, XML_MROOT,sal_True,
1123*cdf0e10cSrcweir             sal_True);
1124*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(2), nLevel+1);
1125*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);
1126*cdf0e10cSrcweir     }
1127*cdf0e10cSrcweir     else
1128*cdf0e10cSrcweir     {
1129*cdf0e10cSrcweir         SvXMLElementExport aSqrt(*this, XML_NAMESPACE_MATH, XML_MSQRT,sal_True,
1130*cdf0e10cSrcweir             sal_True);
1131*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(2), nLevel+1);
1132*cdf0e10cSrcweir     }
1133*cdf0e10cSrcweir }
1134*cdf0e10cSrcweir 
1135*cdf0e10cSrcweir void SmXMLExport::ExportOperator(const SmNode *pNode, int nLevel)
1136*cdf0e10cSrcweir {
1137*cdf0e10cSrcweir     /*we need to either use content or font and size attributes
1138*cdf0e10cSrcweir      *here*/
1139*cdf0e10cSrcweir #if 0
1140*cdf0e10cSrcweir     {
1141*cdf0e10cSrcweir     SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1142*cdf0e10cSrcweir         sal_True,sal_False);
1143*cdf0e10cSrcweir     SmTextNode *pTemp = (SmTextNode *)pNode->GetSubNode(0);
1144*cdf0e10cSrcweir     GetDocHandler()->characters(pTemp->GetText());
1145*cdf0e10cSrcweir     }
1146*cdf0e10cSrcweir #endif
1147*cdf0e10cSrcweir     SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MROW,
1148*cdf0e10cSrcweir         sal_True, sal_True);
1149*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(0), nLevel+1);
1150*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(1), nLevel+1);
1151*cdf0e10cSrcweir }
1152*cdf0e10cSrcweir 
1153*cdf0e10cSrcweir void SmXMLExport::ExportAttributes(const SmNode *pNode, int nLevel)
1154*cdf0e10cSrcweir {
1155*cdf0e10cSrcweir     SvXMLElementExport *pElement=0;
1156*cdf0e10cSrcweir 
1157*cdf0e10cSrcweir     if (pNode->GetToken().eType == TUNDERLINE)
1158*cdf0e10cSrcweir     {
1159*cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENTUNDER,
1160*cdf0e10cSrcweir             XML_TRUE);
1161*cdf0e10cSrcweir         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MUNDER,
1162*cdf0e10cSrcweir             sal_True,sal_True);
1163*cdf0e10cSrcweir     }
1164*cdf0e10cSrcweir     else if (pNode->GetToken().eType != TOVERSTRIKE)
1165*cdf0e10cSrcweir     {
1166*cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT,
1167*cdf0e10cSrcweir             XML_TRUE);
1168*cdf0e10cSrcweir         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MOVER,
1169*cdf0e10cSrcweir             sal_True,sal_True);
1170*cdf0e10cSrcweir     }
1171*cdf0e10cSrcweir 
1172*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(1), nLevel+1);
1173*cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1174*cdf0e10cSrcweir     {
1175*cdf0e10cSrcweir         case TOVERLINE:
1176*cdf0e10cSrcweir             {
1177*cdf0e10cSrcweir             //proper entity support required
1178*cdf0e10cSrcweir             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1179*cdf0e10cSrcweir                 sal_True,sal_True);
1180*cdf0e10cSrcweir #if 0
1181*cdf0e10cSrcweir             GetDocHandler()->characters(
1182*cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM("&overbar;")));
1183*cdf0e10cSrcweir #else
1184*cdf0e10cSrcweir             sal_Unicode nArse[2] = {0xAF,0x00};
1185*cdf0e10cSrcweir #endif
1186*cdf0e10cSrcweir             GetDocHandler()->characters(nArse);
1187*cdf0e10cSrcweir             }
1188*cdf0e10cSrcweir             break;
1189*cdf0e10cSrcweir         case TUNDERLINE:
1190*cdf0e10cSrcweir             {
1191*cdf0e10cSrcweir             //proper entity support required
1192*cdf0e10cSrcweir             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1193*cdf0e10cSrcweir                 sal_True,sal_True);
1194*cdf0e10cSrcweir #if 0
1195*cdf0e10cSrcweir             GetDocHandler()->characters(
1196*cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM("&underbar;")));
1197*cdf0e10cSrcweir #else
1198*cdf0e10cSrcweir             sal_Unicode nArse[2] = {0x0332,0x00};
1199*cdf0e10cSrcweir #endif
1200*cdf0e10cSrcweir             GetDocHandler()->characters(nArse);
1201*cdf0e10cSrcweir             }
1202*cdf0e10cSrcweir             break;
1203*cdf0e10cSrcweir         case TOVERSTRIKE:
1204*cdf0e10cSrcweir             break;
1205*cdf0e10cSrcweir         default:
1206*cdf0e10cSrcweir             ExportNodes(pNode->GetSubNode(0), nLevel+1);
1207*cdf0e10cSrcweir             break;
1208*cdf0e10cSrcweir     }
1209*cdf0e10cSrcweir     delete pElement;
1210*cdf0e10cSrcweir }
1211*cdf0e10cSrcweir 
1212*cdf0e10cSrcweir static bool lcl_HasEffectOnMathvariant( const SmTokenType eType )
1213*cdf0e10cSrcweir {
1214*cdf0e10cSrcweir     return  eType == TBOLD || eType == TNBOLD ||
1215*cdf0e10cSrcweir             eType == TITALIC || eType == TNBOLD ||
1216*cdf0e10cSrcweir             eType == TSANS || eType == TSERIF || eType == TFIXED;
1217*cdf0e10cSrcweir }
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir void SmXMLExport::ExportFont(const SmNode *pNode, int nLevel)
1220*cdf0e10cSrcweir {
1221*cdf0e10cSrcweir     SvXMLElementExport *pElement = 0;
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir     //
1224*cdf0e10cSrcweir     // gather the mathvariant attribut relevant data from all
1225*cdf0e10cSrcweir     // successively following SmFontNodes...
1226*cdf0e10cSrcweir     //
1227*cdf0e10cSrcweir     int nBold   = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1228*cdf0e10cSrcweir     int nItalic = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1229*cdf0e10cSrcweir     int nSansSerifFixed   = -1;
1230*cdf0e10cSrcweir     SmTokenType eNodeType = TUNKNOWN;
1231*cdf0e10cSrcweir     while (lcl_HasEffectOnMathvariant( (eNodeType = pNode->GetToken().eType) ))
1232*cdf0e10cSrcweir     {
1233*cdf0e10cSrcweir         switch (eNodeType)
1234*cdf0e10cSrcweir         {
1235*cdf0e10cSrcweir             case TBOLD      : nBold   = 1; break;
1236*cdf0e10cSrcweir             case TNBOLD     : nBold   = 0; break;
1237*cdf0e10cSrcweir             case TITALIC    : nItalic = 1; break;
1238*cdf0e10cSrcweir             case TNITALIC   : nItalic = 0; break;
1239*cdf0e10cSrcweir             case TSANS      : nSansSerifFixed  = 0; break;
1240*cdf0e10cSrcweir             case TSERIF     : nSansSerifFixed  = 1; break;
1241*cdf0e10cSrcweir             case TFIXED     : nSansSerifFixed  = 2; break;
1242*cdf0e10cSrcweir             default:
1243*cdf0e10cSrcweir                 DBG_ASSERT( 0, "unexpected case" );
1244*cdf0e10cSrcweir         }
1245*cdf0e10cSrcweir         // According to the parser every node that is to be evaluated heres
1246*cdf0e10cSrcweir         // has a single non-zero subnode at index 1!! Thus we only need to check
1247*cdf0e10cSrcweir         // that single node for follow-up nodes that have an effect on the attribute.
1248*cdf0e10cSrcweir         if (pNode->GetNumSubNodes() > 1 && pNode->GetSubNode(1) &&
1249*cdf0e10cSrcweir             lcl_HasEffectOnMathvariant( pNode->GetSubNode(1)->GetToken().eType))
1250*cdf0e10cSrcweir         {
1251*cdf0e10cSrcweir             pNode = pNode->GetSubNode(1);
1252*cdf0e10cSrcweir         }
1253*cdf0e10cSrcweir         else
1254*cdf0e10cSrcweir             break;
1255*cdf0e10cSrcweir     }
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1258*cdf0e10cSrcweir     {
1259*cdf0e10cSrcweir         //wrap a phantom element around everything*/
1260*cdf0e10cSrcweir         case TPHANTOM:
1261*cdf0e10cSrcweir             pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1262*cdf0e10cSrcweir                 XML_MPHANTOM, sal_True,sal_True);
1263*cdf0e10cSrcweir             break;
1264*cdf0e10cSrcweir         case TBLACK:
1265*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLACK);
1266*cdf0e10cSrcweir             break;
1267*cdf0e10cSrcweir         case TWHITE:
1268*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_WHITE);
1269*cdf0e10cSrcweir             break;
1270*cdf0e10cSrcweir         case TRED:
1271*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_RED);
1272*cdf0e10cSrcweir             break;
1273*cdf0e10cSrcweir         case TGREEN:
1274*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_GREEN);
1275*cdf0e10cSrcweir             break;
1276*cdf0e10cSrcweir         case TBLUE:
1277*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLUE);
1278*cdf0e10cSrcweir             break;
1279*cdf0e10cSrcweir         case TCYAN:
1280*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_AQUA);
1281*cdf0e10cSrcweir             break;
1282*cdf0e10cSrcweir         case TMAGENTA:
1283*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_FUCHSIA);
1284*cdf0e10cSrcweir             break;
1285*cdf0e10cSrcweir         case TYELLOW:
1286*cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_YELLOW);
1287*cdf0e10cSrcweir             break;
1288*cdf0e10cSrcweir         case TSIZE:
1289*cdf0e10cSrcweir             {
1290*cdf0e10cSrcweir                 const SmFontNode *pFontNode = static_cast<const SmFontNode *>(pNode);
1291*cdf0e10cSrcweir                 const Fraction &aFrac = pFontNode->GetSizeParameter();
1292*cdf0e10cSrcweir 
1293*cdf0e10cSrcweir                 OUStringBuffer sStrBuf;
1294*cdf0e10cSrcweir                 switch(pFontNode->GetSizeType())
1295*cdf0e10cSrcweir                 {
1296*cdf0e10cSrcweir                     case FNTSIZ_MULTIPLY:
1297*cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1298*cdf0e10cSrcweir                             static_cast<double>(aFrac*Fraction(100.00)));
1299*cdf0e10cSrcweir                         sStrBuf.append(static_cast<sal_Unicode>('%'));
1300*cdf0e10cSrcweir                         break;
1301*cdf0e10cSrcweir                     case FNTSIZ_DIVIDE:
1302*cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1303*cdf0e10cSrcweir                             static_cast<double>(Fraction(100.00)/aFrac));
1304*cdf0e10cSrcweir                         sStrBuf.append(static_cast<sal_Unicode>('%'));
1305*cdf0e10cSrcweir                         break;
1306*cdf0e10cSrcweir                     case FNTSIZ_ABSOLUT:
1307*cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1308*cdf0e10cSrcweir                             static_cast<double>(aFrac));
1309*cdf0e10cSrcweir                         sStrBuf.append(
1310*cdf0e10cSrcweir                             GetXMLToken(XML_UNIT_PT));
1311*cdf0e10cSrcweir                         break;
1312*cdf0e10cSrcweir                     default:
1313*cdf0e10cSrcweir                         {
1314*cdf0e10cSrcweir                             //The problem here is that the wheels fall off because
1315*cdf0e10cSrcweir                             //font size is stored in 100th's of a mm not pts, and
1316*cdf0e10cSrcweir                             //rounding errors take their toll on the original
1317*cdf0e10cSrcweir                             //value specified in points.
1318*cdf0e10cSrcweir 
1319*cdf0e10cSrcweir                             //Must fix StarMath to retain the original pt values
1320*cdf0e10cSrcweir                             Fraction aTemp = Sm100th_mmToPts(pFontNode->GetFont().
1321*cdf0e10cSrcweir                                 GetSize().Height());
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir                             if (pFontNode->GetSizeType() == FNTSIZ_MINUS)
1324*cdf0e10cSrcweir                                 aTemp-=aFrac;
1325*cdf0e10cSrcweir                             else
1326*cdf0e10cSrcweir                                 aTemp+=aFrac;
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir                             double mytest = static_cast<double>(aTemp);
1329*cdf0e10cSrcweir 
1330*cdf0e10cSrcweir                             mytest = ::rtl::math::round(mytest,1);
1331*cdf0e10cSrcweir                             SvXMLUnitConverter::convertDouble(sStrBuf,mytest);
1332*cdf0e10cSrcweir                             sStrBuf.append(GetXMLToken(XML_UNIT_PT));
1333*cdf0e10cSrcweir                         }
1334*cdf0e10cSrcweir                         break;
1335*cdf0e10cSrcweir                 }
1336*cdf0e10cSrcweir 
1337*cdf0e10cSrcweir                 OUString sStr(sStrBuf.makeStringAndClear());
1338*cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHSIZE, sStr);
1339*cdf0e10cSrcweir             }
1340*cdf0e10cSrcweir             break;
1341*cdf0e10cSrcweir         case TBOLD:
1342*cdf0e10cSrcweir         case TITALIC:
1343*cdf0e10cSrcweir         case TNBOLD:
1344*cdf0e10cSrcweir         case TNITALIC:
1345*cdf0e10cSrcweir         case TFIXED:
1346*cdf0e10cSrcweir         case TSANS:
1347*cdf0e10cSrcweir         case TSERIF:
1348*cdf0e10cSrcweir             {
1349*cdf0e10cSrcweir                 // nBold:   -1 = yet undefined; 0 = false; 1 = true;
1350*cdf0e10cSrcweir                 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
1351*cdf0e10cSrcweir                 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
1352*cdf0e10cSrcweir                 const sal_Char *pText = "normal";
1353*cdf0e10cSrcweir                 if (nSansSerifFixed == -1 || nSansSerifFixed == 1)
1354*cdf0e10cSrcweir                 {
1355*cdf0e10cSrcweir                     pText = "normal";
1356*cdf0e10cSrcweir                     if (nBold == 1 && nItalic != 1)
1357*cdf0e10cSrcweir                         pText = "bold";
1358*cdf0e10cSrcweir                     else if (nBold != 1 && nItalic == 1)
1359*cdf0e10cSrcweir                         pText = "italic";
1360*cdf0e10cSrcweir                     else if (nBold == 1 && nItalic == 1)
1361*cdf0e10cSrcweir                         pText = "bold-italic";
1362*cdf0e10cSrcweir                 }
1363*cdf0e10cSrcweir                 else if (nSansSerifFixed == 0)
1364*cdf0e10cSrcweir                 {
1365*cdf0e10cSrcweir                     pText = "sans-serif";
1366*cdf0e10cSrcweir                     if (nBold == 1 && nItalic != 1)
1367*cdf0e10cSrcweir                         pText = "bold-sans-serif";
1368*cdf0e10cSrcweir                     else if (nBold != 1 && nItalic == 1)
1369*cdf0e10cSrcweir                         pText = "sans-serif-italic";
1370*cdf0e10cSrcweir                     else if (nBold == 1 && nItalic == 1)
1371*cdf0e10cSrcweir                         pText = "sans-serif-bold-italic";
1372*cdf0e10cSrcweir                 }
1373*cdf0e10cSrcweir                 else if (nSansSerifFixed == 2)
1374*cdf0e10cSrcweir                     pText = "monospace";    // no modifiers allowed for monospace ...
1375*cdf0e10cSrcweir                 else
1376*cdf0e10cSrcweir                 {
1377*cdf0e10cSrcweir                     DBG_ASSERT( 0, "unexpected case" );
1378*cdf0e10cSrcweir                 }
1379*cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, A2OU(pText));
1380*cdf0e10cSrcweir             }
1381*cdf0e10cSrcweir             break;
1382*cdf0e10cSrcweir         default:
1383*cdf0e10cSrcweir             break;
1384*cdf0e10cSrcweir 
1385*cdf0e10cSrcweir     }
1386*cdf0e10cSrcweir #if 0
1387*cdf0e10cSrcweir     if (pNode->GetNumSubNodes() > 1) //or in the future is a node that
1388*cdf0e10cSrcweir                                      //cannot take the currently supported
1389*cdf0e10cSrcweir                                      //properties
1390*cdf0e10cSrcweir #endif
1391*cdf0e10cSrcweir     //for now we will just always export with a style and not worry about
1392*cdf0e10cSrcweir     //anyone else for the moment.
1393*cdf0e10cSrcweir     {
1394*cdf0e10cSrcweir         //wrap a style around it
1395*cdf0e10cSrcweir         SvXMLElementExport aStyle(*this, XML_NAMESPACE_MATH, XML_MSTYLE, sal_True,sal_True);
1396*cdf0e10cSrcweir         ExportExpression(pNode, nLevel);
1397*cdf0e10cSrcweir     }
1398*cdf0e10cSrcweir #if 0
1399*cdf0e10cSrcweir     else
1400*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);
1401*cdf0e10cSrcweir #endif
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir     delete pElement;
1404*cdf0e10cSrcweir }
1405*cdf0e10cSrcweir 
1406*cdf0e10cSrcweir 
1407*cdf0e10cSrcweir void SmXMLExport::ExportVerticalBrace(const SmNode *pNode, int nLevel)
1408*cdf0e10cSrcweir {
1409*cdf0e10cSrcweir     //Place the overbrace value OVER a vertical brace and then place that
1410*cdf0e10cSrcweir     //expression OVER the overbrace value, If someone can find a
1411*cdf0e10cSrcweir     //dedicated term in MathML to handle this overbrace/underbrace concept
1412*cdf0e10cSrcweir     //let me know. C.
1413*cdf0e10cSrcweir     XMLTokenEnum which;
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1416*cdf0e10cSrcweir     {
1417*cdf0e10cSrcweir         case TOVERBRACE:
1418*cdf0e10cSrcweir         default:
1419*cdf0e10cSrcweir             which = XML_MOVER;
1420*cdf0e10cSrcweir             break;
1421*cdf0e10cSrcweir         case TUNDERBRACE:
1422*cdf0e10cSrcweir             which = XML_MUNDER;
1423*cdf0e10cSrcweir             break;
1424*cdf0e10cSrcweir     }
1425*cdf0e10cSrcweir 
1426*cdf0e10cSrcweir     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Vertical Brace");
1427*cdf0e10cSrcweir     SvXMLElementExport aOver1(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
1428*cdf0e10cSrcweir     {//Scoping
1429*cdf0e10cSrcweir         // using accents will draw the over-/underbraces too close to the base
1430*cdf0e10cSrcweir         // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
1431*cdf0e10cSrcweir         // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
1432*cdf0e10cSrcweir //        AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT, XML_sal_True);
1433*cdf0e10cSrcweir         SvXMLElementExport aOver2(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
1434*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel);
1435*cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(1), nLevel);
1436*cdf0e10cSrcweir     }
1437*cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(2), nLevel);
1438*cdf0e10cSrcweir }
1439*cdf0e10cSrcweir 
1440*cdf0e10cSrcweir void SmXMLExport::ExportMatrix(const SmNode *pNode, int nLevel)
1441*cdf0e10cSrcweir {
1442*cdf0e10cSrcweir     SvXMLElementExport aTable(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
1443*cdf0e10cSrcweir     const SmMatrixNode *pMatrix = static_cast<const SmMatrixNode *>(pNode);
1444*cdf0e10cSrcweir     sal_uInt16 i=0;
1445*cdf0e10cSrcweir     for (sal_uLong y = 0; y < pMatrix->GetNumRows(); y++)
1446*cdf0e10cSrcweir     {
1447*cdf0e10cSrcweir         SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
1448*cdf0e10cSrcweir         for (sal_uLong x = 0; x < pMatrix->GetNumCols(); x++)
1449*cdf0e10cSrcweir             if (const SmNode *pTemp = pNode->GetSubNode(i++))
1450*cdf0e10cSrcweir             {
1451*cdf0e10cSrcweir                 SvXMLElementExport aCell(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
1452*cdf0e10cSrcweir                 ExportNodes(pTemp, nLevel+1);
1453*cdf0e10cSrcweir             }
1454*cdf0e10cSrcweir     }
1455*cdf0e10cSrcweir }
1456*cdf0e10cSrcweir 
1457*cdf0e10cSrcweir void SmXMLExport::ExportNodes(const SmNode *pNode, int nLevel)
1458*cdf0e10cSrcweir {
1459*cdf0e10cSrcweir     if (!pNode)
1460*cdf0e10cSrcweir         return;
1461*cdf0e10cSrcweir     switch(pNode->GetType())
1462*cdf0e10cSrcweir     {
1463*cdf0e10cSrcweir         case NTABLE:
1464*cdf0e10cSrcweir             ExportTable(pNode, nLevel);
1465*cdf0e10cSrcweir             break;
1466*cdf0e10cSrcweir         case NALIGN:
1467*cdf0e10cSrcweir         case NBRACEBODY:
1468*cdf0e10cSrcweir         case NEXPRESSION:
1469*cdf0e10cSrcweir             ExportExpression(pNode, nLevel);
1470*cdf0e10cSrcweir             break;
1471*cdf0e10cSrcweir         case NLINE:
1472*cdf0e10cSrcweir             ExportLine(pNode, nLevel);
1473*cdf0e10cSrcweir             break;
1474*cdf0e10cSrcweir         case NTEXT:
1475*cdf0e10cSrcweir             ExportText(pNode, nLevel);
1476*cdf0e10cSrcweir             break;
1477*cdf0e10cSrcweir         case NSPECIAL: //NSPECIAL requires some sort of Entity preservation in the XML engine.
1478*cdf0e10cSrcweir         case NGLYPH_SPECIAL:
1479*cdf0e10cSrcweir         case NMATH:
1480*cdf0e10cSrcweir             {
1481*cdf0e10cSrcweir                 sal_Unicode cTmp = 0;
1482*cdf0e10cSrcweir                 const SmTextNode *pTemp = static_cast< const SmTextNode * >(pNode);
1483*cdf0e10cSrcweir                 if (pTemp->GetText().Len() > 0)
1484*cdf0e10cSrcweir                     cTmp = ConvertMathToMathML( pTemp->GetText().GetChar(0) );
1485*cdf0e10cSrcweir                 if (cTmp == 0)
1486*cdf0e10cSrcweir                 {
1487*cdf0e10cSrcweir                     // no conversion to MathML implemented -> export it as text
1488*cdf0e10cSrcweir                     // thus at least it will not vanish into nothing
1489*cdf0e10cSrcweir                     ExportText(pNode, nLevel);
1490*cdf0e10cSrcweir                 }
1491*cdf0e10cSrcweir                 else
1492*cdf0e10cSrcweir                 {
1493*cdf0e10cSrcweir                     //To fully handle generic MathML we need to implement the full
1494*cdf0e10cSrcweir                     //operator dictionary, we will generate MathML with explicit
1495*cdf0e10cSrcweir                     //stretchiness for now.
1496*cdf0e10cSrcweir                     sal_Int16 nLength = GetAttrList().getLength();
1497*cdf0e10cSrcweir                     sal_Bool bAddStretch=sal_True;
1498*cdf0e10cSrcweir                     for ( sal_Int16 i = 0; i < nLength; i++ )
1499*cdf0e10cSrcweir                     {
1500*cdf0e10cSrcweir                         OUString sLocalName;
1501*cdf0e10cSrcweir                         sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName(
1502*cdf0e10cSrcweir                             GetAttrList().getNameByIndex(i), &sLocalName );
1503*cdf0e10cSrcweir 
1504*cdf0e10cSrcweir                         if ( ( XML_NAMESPACE_MATH == nPrefix ) &&
1505*cdf0e10cSrcweir                             IsXMLToken(sLocalName, XML_STRETCHY) )
1506*cdf0e10cSrcweir                         {
1507*cdf0e10cSrcweir                             bAddStretch = sal_False;
1508*cdf0e10cSrcweir                             break;
1509*cdf0e10cSrcweir                         }
1510*cdf0e10cSrcweir                     }
1511*cdf0e10cSrcweir                     if (bAddStretch)
1512*cdf0e10cSrcweir                     {
1513*cdf0e10cSrcweir                         AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1514*cdf0e10cSrcweir                     }
1515*cdf0e10cSrcweir                     ExportMath(pNode, nLevel);
1516*cdf0e10cSrcweir                 }
1517*cdf0e10cSrcweir             }
1518*cdf0e10cSrcweir             break;
1519*cdf0e10cSrcweir         case NPLACE:
1520*cdf0e10cSrcweir             ExportMath(pNode, nLevel);
1521*cdf0e10cSrcweir             break;
1522*cdf0e10cSrcweir         case NBINHOR:
1523*cdf0e10cSrcweir             ExportBinaryHorizontal(pNode, nLevel);
1524*cdf0e10cSrcweir             break;
1525*cdf0e10cSrcweir         case NUNHOR:
1526*cdf0e10cSrcweir             ExportUnaryHorizontal(pNode, nLevel);
1527*cdf0e10cSrcweir             break;
1528*cdf0e10cSrcweir         case NBRACE:
1529*cdf0e10cSrcweir             ExportBrace(pNode, nLevel);
1530*cdf0e10cSrcweir             break;
1531*cdf0e10cSrcweir         case NBINVER:
1532*cdf0e10cSrcweir             ExportBinaryVertical(pNode, nLevel);
1533*cdf0e10cSrcweir             break;
1534*cdf0e10cSrcweir         case NSUBSUP:
1535*cdf0e10cSrcweir             ExportSubSupScript(pNode, nLevel);
1536*cdf0e10cSrcweir             break;
1537*cdf0e10cSrcweir         case NROOT:
1538*cdf0e10cSrcweir             ExportRoot(pNode, nLevel);
1539*cdf0e10cSrcweir             break;
1540*cdf0e10cSrcweir         case NOPER:
1541*cdf0e10cSrcweir             ExportOperator(pNode, nLevel);
1542*cdf0e10cSrcweir             break;
1543*cdf0e10cSrcweir         case NATTRIBUT:
1544*cdf0e10cSrcweir             ExportAttributes(pNode, nLevel);
1545*cdf0e10cSrcweir             break;
1546*cdf0e10cSrcweir         case NFONT:
1547*cdf0e10cSrcweir             ExportFont(pNode, nLevel);
1548*cdf0e10cSrcweir             break;
1549*cdf0e10cSrcweir         case NVERTICAL_BRACE:
1550*cdf0e10cSrcweir             ExportVerticalBrace(pNode, nLevel);
1551*cdf0e10cSrcweir             break;
1552*cdf0e10cSrcweir         case NMATRIX:
1553*cdf0e10cSrcweir             ExportMatrix(pNode, nLevel);
1554*cdf0e10cSrcweir             break;
1555*cdf0e10cSrcweir         case NBLANK:
1556*cdf0e10cSrcweir             ExportBlank(pNode, nLevel);
1557*cdf0e10cSrcweir             break;
1558*cdf0e10cSrcweir        default:
1559*cdf0e10cSrcweir             DBG_ASSERT( 0, "Warning: failed to export a node?" );
1560*cdf0e10cSrcweir             break;
1561*cdf0e10cSrcweir 
1562*cdf0e10cSrcweir #if 0
1563*cdf0e10cSrcweir         default:
1564*cdf0e10cSrcweir             {
1565*cdf0e10cSrcweir             sal_uLong  nSize = pNode->GetNumSubNodes();
1566*cdf0e10cSrcweir             for (sal_uLong i = 0; i < nSize; i++)
1567*cdf0e10cSrcweir                 if (SmNode *pTemp = pNode->GetSubNode(i))
1568*cdf0e10cSrcweir                     ExportNodes(pTemp, nLevel+1);
1569*cdf0e10cSrcweir             }
1570*cdf0e10cSrcweir             break;
1571*cdf0e10cSrcweir #endif
1572*cdf0e10cSrcweir     }
1573*cdf0e10cSrcweir }
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir ////////////////////////////////////////////////////////////
1576*cdf0e10cSrcweir 
1577