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